I am trying to write tests for Django/DjangoREST project. I have decided to use pytest. I have poor experience in writing tests for Django projects specifically. So I am confused now.
Here is an example:
@pytest.mark.django_db
def test_some_view(
api_client,
simple_user,
model1_factory,
model2_factory,
... # many other model factories
modelN_factory
):
# ...
# creating here other objects that really depends on each other
# ...
model2_obj = ... # model2 object on its own side depends on model3, model4... and so on
model1_objs = []
for i in range(10):
model1_objs.append(model1_factory(some_field=100, some_model2_rel=model2_obj)
assert len(model1_objs) == 1, "Created items with duplicate `some_field`"
As you can see I have too many factories to be used in one test. But looking at my model structure right now, I can't think of a better way. Is it ok to use so many factories for one test? Or should I find some issues related to my tables' relations?
Any help is appreciated. Thanks in advance
The main goal of factory_boy is getting rid of fixtures; its typical use case is:
Factory
classes, which are basically recipes for getting a "realistic" object instanceAs I understand it, pytest fixtures are intended for "setting up the test environment": booting the database, mocking an external service, etc.; creating objects inside the database isn't a good fit for them.
The way I'd write your code would be the following:
We have a factory for an employee, and one for a division - and each employee gets assigned to a division. Every mandatory field is provided; if we need to make specific factories for some object profiles, this can be added through either subclassing or using traits.
We can now write our tests, passing only the details required for the test:
As a side note, wouldn't it make more sense to use Django's test runner directly? It's more finely tuned for Django internals: each test can be natively wrapped in a sub-transaction for performance, the test client provides helpers for in-depth introspection of view results, etc.