![]() ![]() The definition of the rest of the factories follow the same pattern - we won't add it here to keep the example short. Sales_member = factory.SubFactory(UserFactory) Vehicle = factory.SubFactory(VehicleFactory)Ĭustomer = factory.SubFactory(UserFactory) Price = factory.LazyAttribute(lambda _: faker.pyfloat(positive=True)) Name = factory.LazyAttribute(lambda _: faker.name())Įmail = factory.LazyAttribute(lambda _: ())Ĭlass VehiclePurchaseFactory(): Here is how the Factory for our VehiclePurchase looks like: # in my_project/current_app/tests/factories.pyĬlass UserFactory(): It's more compact and we've moved the actual creation logic elsewhere. Self.vehicle_purchase = test_vehicle_purchase_cancel_sets_cancelled_at(self, now_mock): Here is how the above example looks like, when you use Model Factories: class VehiclePurchaseCancelTests(unittest.TestCase): Plan = (name='Example plan', price=100.0)Īs you can see, things can pile up quickly and become harder to maintain. Make = (name='Volkswagen', abbreviation='VW')Ĭategory = (name='SUV', doors_count=5) ![]() class VehiclePurchaseCancelTests(unittest.TestCase):Ĭustomer = (name='Customer', = (name='Sales', = (hex_code='#00000', display_name='White') Simple enough, right? Well, here is how the setUp method of this TestCase looks like without Factories. Self.assertEqual(updated_vehicle_purchase.cancelled_at, now_mock.return_value) Updated_vehicle_purchase = vehicle_purchase_cancel( Let's say we'd like to add the following unit test: class test_vehicle_purchase_cancel_sets_cancelled_at(self, now_mock): This service is a critical feature for our application and we want to test it exhaustively. Return vehicle_purchase You can check our Django Styleguide for more information about the services terminology. Vehicle_purchase.cancelled_at = timezone.now() If vehicle_purchase.cancelled_at is not None: We have a simple service that handles purchase cancellations: def vehicle_purchase_cancel(*, vehicle_purchase: VehiclePurchase) -> VehiclePurchase: For example, the Vehicle model would have a relation to a manufacturer, to a vehicle model and so on. There is something that we'd like to point out here - the foreign key relations of our example model have required foreign key relations on their own. ![]() I'm sure you can imagine how many other relations would this model have in a more realistic example. This is a very basic representation of a vehicle purchase. Requested_at = models.DateTimeField(db_index=True, default=timezone.now)Ĭancelled_at = models.DateTimeField(null=True, blank=True) Plan = models.ForeignKey(Plan, on_delete=models.CASCADE)īaseUser, null=True, blank=True, on_delete=models.SET_NULL Vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE) VehicleColor, null=True, blank=True, on_delete=models.SET_NULL Price = models.DecimalField(max_digits=19, decimal_places=2) We represent this in the database with the following model: from django.db import models We have a feature in our app that is used by our sales team to purchase vehicles. In this article, we're going to be vehicle dealers. ![]() The versions of the packages that we're going to use in the blog post: Django=3.2.9 We use Faker to achieve this! It's a package that generates fake data that perfectly fits with the idea of the factories and the randomization of the input of your unit tests.Įnough said! Let's look at some practical examples. The point is that we'd want these model instances to be generated with different fields. OK, now we know what to use to setup objects for our unit tests easily. In all our Django projects, we use factory_boy to achieve this. Their main goal is to allow the developers to focus on the tests themselves rather than on their setup. They can highly improve the maintainability, the readability and the development time of your tests. Introducing them to your projects would solve the above problems.įactories aim to simplify your tests' setup by providing an easy-to-use interface for building complicated objects and relations. The Model Factories are an upgrade over this process. When it comes to unit testing, you can always use your models directly.ĭoing so, over a period of time, can introduce a lot of verbosity and you'd have to copy-paste the same code setup many times. It's really common that you can't even create a model instance without having other instances created (because of one-to-one and foreign key relations). The model structure of a Django project is usually complicated. Any idea why?Īpps/user/tests/factories.py class CompanyFactory():Ĭlass UserFactory(, November 2021: The article was rewritten to provide better & up to date examples, about fakes & factories in Django. I set up ~100 unit test for a django app, and later realized each unit test run was creating test users in my local database, instead of the test database. ![]()
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |