Pytest fixtures

Polyfactory support registering factories as pytest fixtures using the register_fixture decorator:

Using the register_fixture_decorator field.
from dataclasses import dataclass
from datetime import date, datetime
from typing import List, Optional, Union
from uuid import UUID

from polyfactory.factories import DataclassFactory
from polyfactory.pytest_plugin import register_fixture


@dataclass
class Person:
    id: UUID
    name: str
    hobbies: Optional[List[str]]
    nicks: List[str]
    age: Union[float, int]
    birthday: Union[datetime, date]


@register_fixture
class PersonFactory(DataclassFactory[Person]): ...


# NOTE: PersonFactory is no more a factory class, it is a callable that returns the decorated factory


def test_person_factory(person_factory: DataclassFactory[Person]) -> None:
    person_instance = person_factory.build()
    assert isinstance(person_instance, Person)

In the above example the PersonFactory is wrapped as a pytest fixture. As a result it cannot be used as a normal factory,because pytest fixtures are callables that must be called by pytest. To overcome this restriction, you can declare the fixture separately from the declaration of the class:

Using the register_fixture_decorator field without wrapping the factory class.
from dataclasses import dataclass
from datetime import date, datetime
from typing import List, Optional, Union
from uuid import UUID

from polyfactory.factories import DataclassFactory
from polyfactory.pytest_plugin import register_fixture


@dataclass
class Person:
    id: UUID
    name: str
    hobbies: Optional[List[str]]
    nicks: List[str]
    age: Union[float, int]
    birthday: Union[datetime, date]


class PersonFactory(DataclassFactory[Person]): ...


person_factory_fixture = register_fixture(PersonFactory)


def test_person_factory(person_factory: PersonFactory) -> None:
    person_instance = person_factory.build()
    assert isinstance(person_instance, Person)

    # we can still access the factory class itself-
    another_person_instance = PersonFactory.build()
    assert isinstance(another_person_instance, Person)

You can also control the name of the fixture using the optional name kwarg:

Aliasing a factory fixture using the name kwarg.
from dataclasses import dataclass
from datetime import date, datetime
from typing import List, Optional, Union
from uuid import UUID

from polyfactory.factories import DataclassFactory
from polyfactory.pytest_plugin import register_fixture


@dataclass
class Person:
    id: UUID
    name: str
    hobbies: Optional[List[str]]
    nicks: List[str]
    age: Union[float, int]
    birthday: Union[datetime, date]


class PersonFactory(DataclassFactory[Person]): ...


person_factory_fixture = register_fixture(PersonFactory, name="aliased_person_factory")


def test_person_factory(aliased_person_factory: PersonFactory) -> None:
    person_instance = aliased_person_factory.build()
    assert isinstance(person_instance, Person)

The Fixture Field

You can also use factory fixtures as factory fields using the Fixture:

Using the Fixture field.
from dataclasses import dataclass
from datetime import date, datetime
from typing import List, Optional, Union
from uuid import UUID

from polyfactory import Fixture
from polyfactory.factories import DataclassFactory
from polyfactory.pytest_plugin import register_fixture


@dataclass
class Person:
    id: UUID
    name: str
    hobbies: Optional[List[str]]
    nicks: List[str]
    age: Union[float, int]
    birthday: Union[datetime, date]


@dataclass
class ClassRoom:
    teacher: Person
    pupils: List[Person]


@register_fixture
class PersonFactory(DataclassFactory[Person]): ...


class ClassRoomFactory(DataclassFactory[ClassRoom]):
    teacher = Fixture(PersonFactory, name="Ludmilla Newman")
    pupils = Fixture(PersonFactory, size=20)


def test_fixture_field() -> None:
    classroom_instance = ClassRoomFactory.build()

    assert isinstance(classroom_instance.teacher, Person)
    assert classroom_instance.teacher.name == "Ludmilla Newman"
    assert len(classroom_instance.pupils) == 20

Fixture is similar to Use in that it accepts kwargs that are propagated the to the build or batch methods of the factory.