Simplifying test creation with model-bakery
Creating fixtures for tests in Django by hand is something very laborious and boring. And writing the tests itself is not always a pleasant task, especially when we need to create fixtures to help us with the tests, generating and updating the dump.json becomes very costly. The model-bakery, with its simple and robust API, can create many objects in a single line of code.
First, let's introduce the models file with which we are going to work:
Based on these models, let's create a test example using fixtures. Let's generate this fixtures with the result of the manage.py dumpdata
command, which generated a file with data from 206 registered products.
In this specific case, the file load_products.json can easily be replaced by one line of code using model-bakery.
As we can see, we generated two hundred objects in just one line of code. Looking closer to this line, we have the model Product, then the attribute _quantity
with the number of objects we want to create. Later we will see how to combine the attribute _quantity
with another really cool attribute called seq
.
Model Relationships
Another point that I really like is the simplicity in which the bakery works with relationships, be it many-to-many
or one-to-one
, let’s see some examples:
By default, the model-bakery does not automatically create related instances m2m, you need to pass the attribute make_m2m=True
. If you want something more explicit, you could do it like this:
Pytest & model-bakery
While working on legacy projects, it is normal to find yourself using two or more libs for writing tests, such as pytest and model-bakery. In my opinion, it is a perfect marriage. In pytest it is common to see the use of the decorator @pytest.fixture
centered on the named file conftest.py or directly in your test file. At the model-bakery we use the Recipes to avoid code duplication, and if you are not comfortable with randomly generated data, using Recipes is a great idea. The following example shows a case using both libraries:
You can even combine the use of @pytest.fixture
and model-bakery
as follows:
This was a very simple example just to demonstrate how easy it is to associate these two libs, making your tests increasingly simpler to understand, with low complexity and easy maintenance.
Creating objects without persisting in the database
At some point, you will find your test build getting slower every day, especially if your tests need to create a lot of objects. For this, we can use the method to prepare. Repare works much like make, being able to take advantage of all the attributes, without having to save the data on your database.
If you need to save information in the table that relates to the PurchaseHistory table, you can use the _save_related
, see in the example below how it would be:
As observed, we can see how interesting it is to use model-bakery. Its use with different libraries (such as Pytest) facilitates the addition of features and even simplifies testing, in addition to a lean and relatively intuitive API. Do you have any questions or suggestions? Leave your message in the comments and until next time!
References:
Model Bakery: Smart fixtures for better tests — Model Bakery 1.11.0 documentation
GitHub - model-bakers/model_bakery: Object factory for Django
Escrevendo testes melhores com Model-bakery - Higor Monteiro [PyBR2022]