Package: pytest-django-factories
pytest-django-factoriesFactories for your Django models that can be used as Pytest fixtures.
Re-use them implicitly for instantiating related objects without much boilerplate code.>>>book=book_factory(title="Calvin & Hobbes",author__name="Bill Watterson")>>>book<Book:Calvin&Hobbes>>>>book.author.name<Author:BillWatterson>IntroductionWrite a fixture for your Django model by using theFactoryclass:# conftest.pyimportpytestfromdjango_factoriesimportFactoryfrom.modelsimportAuthor@pytest.fixturedefauthor_factory(request):factory=Factory(Author)returnfactory(request)# tests.pydeftest_function(author_factory):author=author_factory(name="Bill Watterson")assertauthor.name:notebook:NoteTherequestpassed to the fixture function is a pytest fixture itself and provides information about the test function requesting the fixture.
Seepytest documentation.Default valuesA plainFactorywill, of course, instantiate the object with the defaults given at the model definition.
If you want to set defaults for the factory specifically, you can pass them to the Factory as additional
keyword arguments:@pytest.fixturedefauthor_factory(request):defaults={"first_name":"William","last_name":"Watterson","birthdate":"1958-07-05",}returnFactory(Author,**defaults)(request)Related objectsIf you want to test a model which depends on another object being present,
the Factory class will try to look up a matching factory fixture for thatForeignKeyfield
and create the related object automatically for you.
Attributes for the related object can be specified in the same double-underscore syntax that you're familiar with from Django's queryset lookups:@pytest.fixturedefauthor_factory(request):returnFactory(Author)(request)@pytest.fixturedefbook_factory(request):returnFactory(Book)(request)deftest(book_factory):book=book_factory(author__first_name="Astrid",author__last_name="Lindgren")This only works if there is a factory fixture available to create the related object.Factorywill look for a fixture named<field>_factory.
If you have a fixture that you named differently (or you have multiple fixtures for that particular model), you can specify a custom fixture name:@pytest.fixturedefbook_factory(request):returnFactory(Book,author=SubFactory("my_author_fixture"))(request)Passing object instances as keyword arguments instead works as well, of course:book=book_factory(author=Author(first_name="Astrid",last_name="Lindgren"))Database usageYou can useFactoryto instantiate objects in memory and also to create them in the database directly viaModel.objects.create().
If your test function ismarked to use the database, the objects will be saved to the database.
Unmarked tests will only create objects in memory.Customizing a factoryTheFactorycan be subclassed and you can override itscreate(**kwargs)method to customize how objects are instantiated. Here's an example of an auto-enumerating factory for a Book model:fromitertoolsimportcount@pytest.fixturedefbook_factory(request):counter=count(1)classBookFactory(Factory):model=Bookdefcreate(self,**kwargs):returnsuper().create(**kwargs,title=f"Book{next(counter)}")returnBookFactory()(request)Installationpipinstallpytest-django-factoriesContributingAll contributions are welcome. To check out the development version and run the tests, follow these steps:gitclonehttps://github.com/jnns/pytest-django-factories.gitcdpytest-django-factories
python3-mvenv.venvsource.venv/bin/activate
pipinstall-rrequirements.txt
pytestSimilar projectsWhen I wrote this library, I needed a quick and easy way to create related objects using Pytest fixtures.
I didn't know aboutpytest-factoryboy,
which allows registering the powerful factories fromfactory_boyfor Pytest's fixture dependency injection.Basically,pytest-django-factoriesis a less-feature-packed combination of bothfactory_boyandpytest-factoryboythat will hopefully help you get going quickly.