Registry / testing / factory-boy

factory-boy

JSON →
library3.3.3pypypi✓ verified 27d ago

factory-boy is a versatile test fixtures replacement for Python, based on thoughtbot's factory_bot for Ruby. It helps generate fake data efficiently and declaratively for various ORMs like Django, SQLAlchemy, and MongoEngine, supporting multiple build strategies and factory inheritance.

pip install factory-boy
INSTALL
IMPORT
SIG · FACTORY-BOY
F
factory-boy
testingpythonv3.3.3
Install
2.9s avg
Import
330ms
Disk
41MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.3.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.336s · 43.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 2.9s · import 0.324s · 44MB
41MB installed
● package 41MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Factory
import factory class MyFactory(factory.Factory): ...
from factory_boy import Factory
The primary `Factory` class is typically imported from the `factory` namespace.
Faker
import factory class MyFactory(factory.Factory): name = factory.Faker('name')
Used for generating realistic, randomized data.
Sequence
import factory class MyFactory(factory.Factory): id = factory.Sequence(lambda n: n)
Generates sequential values, often used for unique IDs.
LazyAttribute
import factory class MyFactory(factory.Factory): full_name = factory.LazyAttribute(lambda o: f'{o.first_name} {o.last_name}')
Evaluates its argument when the object is built, often dependent on other attributes of the generated object.
SubFactory
import factory class UserFactory(factory.Factory): ... class ProfileFactory(factory.Factory): user = factory.SubFactory(UserFactory)
Used to create and link related objects, calling another factory.
DjangoModelFactory
from factory.django import DjangoModelFactory class UserFactory(DjangoModelFactory): class Meta: model = User
Specific factory for Django ORM models, automatically handling `save()` behavior during `create()`.
SQLAlchemyModelFactory
from factory.alchemy import SQLAlchemyModelFactory class UserFactory(SQLAlchemyModelFactory): class Meta: model = User sqlalchemy_session = db_session
Specific factory for SQLAlchemy models, requiring a session object in `Meta.sqlalchemy_session`.

Define a simple Python class and then create a `factory.Factory` subclass for it. Use `factory.Faker` for realistic data and `factory.LazyAttribute` for interdependent fields. Instances can be created by calling the factory, with keyword arguments overriding default attributes.

import factory class User: def __init__(self, first_name, last_name, email, is_admin=False): self.first_name = first_name self.last_name = last_name self.email = email self.is_admin = is_admin def __str__(self): return f'{self.first_name} {self.last_name} ({self.email})' class UserFactory(factory.Factory): class Meta: model = User first_name = factory.Faker('first_name') last_name = factory.Faker('last_name') email = factory.LazyAttribute(lambda o: f'{o.first_name}.{o.last_name}@example.com'.lower()) is_admin = False # Create a basic user user = UserFactory() print(f"Created user: {user}") # Create an admin user admin_user = UserFactory(is_admin=True) print(f"Created admin user: {admin_user}") # Create a user with specific name specific_user = UserFactory(first_name='John', last_name='Doe') print(f"Created specific user: {specific_user}")
Debug
Known issues
breakingMajor breaking changes occurred in the transition from factory-boy 2.x to 3.x, including dropping support for Python 2, Python 3.4, Django 2.0, and Django 2.1.
fix
Upgrade to Python 3.8+ and supported Django versions. Review the official changelog for specific removals and re-implementations.
affects: 2.x to 3.x
breakingFor plain `factory.Factory` subclasses, `create()` no longer calls `objects.create()` for ORM models. For Django or SQLAlchemy models, you must now use `DjangoModelFactory` or `SQLAlchemyModelFactory` respectively to ensure persistence to the database when calling `create()`.
fix
Migrate your ORM-backed factories to inherit from `factory.django.DjangoModelFactory` or `factory.alchemy.SQLAlchemyModelFactory`.
affects: 2.x to 3.x
deprecatedOld class-level attributes like `FACTORY_FOR`, `ABSTRACT_FACTORY`, `FACTORY_STRATEGY` are deprecated. They should now be defined within a nested `Meta` class using `model`, `abstract`, and `strategy` respectively.
fix
Refactor factory definitions to use the `Meta` class pattern (e.g., `class Meta: model = MyModel`).
affects: 2.x to 3.x
deprecatedThe default behavior of `_after_postgeneration` for `DjangoModelFactory` changed. It will no longer automatically save the instance after post-generation hooks in future releases. This often results in `DeprecationWarning` if not handled.
fix
If your `post_generation` hooks modify the instance, set `skip_postgeneration_save = True` in `Meta` and explicitly call `instance.save()` within your post-generation hook, typically guarding it with `if create:`.
affects: 3.x
gotchaDefining mutable fields (e.g., lists, dictionaries) directly at the factory class level can lead to all generated instances sharing the same mutable object. Changes in one instance will propagate to others.
fix
Use `factory.List()`, `factory.Dict()`, or `factory.LazyAttribute` to ensure each instance receives a unique mutable object. Example: `my_list = factory.List([1, 2, 3])` or `my_dict = factory.LazyAttribute(lambda o: {})`.
affects: All
gotchaOverriding attributes directly at the class level (e.g., `MyFactory.name = 'Fixed'`) is an anti-pattern and can lead to unpredictable behavior, especially in parallel test runs, as it modifies the default for all future objects.
fix
Always specify attribute overrides using keyword arguments in your factory call (e.g., `MyFactory(name='Custom Name')`).
affects: All
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'factory.django'
This error typically occurs when attempting to import `DjangoModelFactory` from the `factory.django` module in older `factory-boy` versions (prior to 3.0) or when `factory-boy` is not installed or the virtual environment is not active. Before version 3.0, `DjangoModelFactory` was directly available under the `factory` namespace.
fix
For `factory-boy` versions 3.0 and above, ensure you are importing `DjangoModelFactory` from `factory.django`. If using an older version (pre-3.0), import it directly from `factory`. Also, confirm that `factory-boy` is installed (`pip install factory-boy`) and your virtual environment is activated.
FactoryError: No model set on <FactoryName>Factory
This error occurs when a `factory.Factory` subclass, especially `DjangoModelFactory`, does not have its `Meta.model` attribute correctly defined, meaning the factory doesn't know which model it should generate instances for.
fix
Inside your factory class, define a `Meta` inner class and set its `model` attribute to the actual Python class of the model you intend to create instances of (e.g., `model = myapp.models.MyModel`), not a string or an instance.
AttributeError: 'str' object has no attribute 'pk'
This `AttributeError` often arises in Django contexts when a `DjangoModelFactory`'s `Meta.model` is incorrectly set to a string literal (e.g., `'myapp.MyModel'`) and an older `factory-boy` version or an improper interaction attempts to access model attributes like `pk` or `objects` directly on this string. While `DjangoModelFactory` *does* support string references for `model`, this specific error points to a situation where the string is not correctly resolved to a model class during an operation that expects an actual model object, or when `factory.Factory` is used instead of `factory.django.DjangoModelFactory`.
fix
Ensure you are inheriting from `factory.django.DjangoModelFactory` for Django models. If the error persists, pass the actual model class to `Meta.model` (e.g., `model = myapp.models.MyModel`) instead of a string path.
django.db.utils.IntegrityError: duplicate key value violates unique constraint
This database error typically occurs in Django tests when `factory-boy` creates model instances with values that violate unique constraints defined in your database schema, often due to not using `factory.Sequence` for unique fields or misconfiguring `django_get_or_create`.
fix
For any model fields that require unique values, use `factory.Sequence(lambda n: f'unique_value_{n}')` to generate distinct values for each instance. If you intend to retrieve existing objects instead of creating duplicates, properly configure `Meta.django_get_or_create = ('unique_field_name',)` with the fields that uniquely identify an object.
Upgrade
Version history
3.3.3latest on PyPI · released Feb 3, 2025
Audit
Dependencies
FakeroptionalCommonly integrated for generating realistic, random data for factory attributes.
Agent activity
13 hits · last 30 days
node
12
Resources
factory-boy — pip install factory-boy · libregistry