factory_bot
Generate realistic test data with ease.
Describe your test data once, and every test can ask for it: build(user), create(user, "admin", first_name="Jane"), build_list(post, 3). Each test spells out only the fields it cares about, and the factory fills in the rest, with believable fake values from Faker when you ask for them. It works with anything that takes keyword arguments: plain classes, dataclasses, dicts, Django and SQLAlchemy models. Under pytest, every test gets the same fake data whether it runs alone, in the suite, or in a different order.
Early development: the API is still settling.
Install
pip install factory_bot
Quick start
from dataclasses import dataclass
from factory_bot import build, create, f, factory, fake, sequence, trait
@dataclass
class User:
first_name: str
last_name: str
email: str
username: str
admin: bool = False
def save(self):
pass # your ORM's save(); create() calls it
@factory(User)
def user():
f.first_name = fake.first_name # no parens: a fresh name on every build
f.last_name = fake.last_name
f.email = lambda first_name, last_name: f"{first_name}.{last_name}@example.com"
f.username = sequence(lambda n: f"user{n}")
@trait
def admin():
f.admin = True
build(user)
# User(first_name='Diane', last_name='Butler', email='Diane.Butler@example.com', username='user1', admin=False)
create(user, "admin", first_name="Jane")
# User(first_name='Jane', last_name='Turner', email='Jane.Turner@example.com', username='user2', admin=True)
A factory is a plain function that assigns attributes to f: no classes, no Meta. A function value, like email's lambda, is called on every build, with its parameters filled from the attributes of the same name. So overrides like first_name="Jane" win, and email follows along. Later traits win over earlier ones, and overrides beat them all.
@factory returns the factory, so build(user) is typed as a User. Its name works too: build("user").
Associations
from factory_bot import association
@factory(dict)
def author():
f.name = "Ann"
@factory(dict)
def book():
f.title = "Dune"
f.author = association(author, name="Frank")
assert build(book) == {"title": "Dune", "author": {"name": "Frank"}}
assert build(book, author_id=7) == {"title": "Dune", "author_id": 7}
An association follows the parent: build builds it, and create creates it first, so it's saved before the row that points at it. Pass your own with author=, or author_id= to skip making one.
Saving
create builds, then calls obj.save(). A Django model needs nothing more.
For SQLAlchemy, hand persist_with the test's session. Each created object is added and flushed, so ids and foreign keys are set, but nothing is committed:
# tests/conftest.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from factory_bot import persist_with
from myapp.models import Base
@pytest.fixture
def session():
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
with Session(engine) as session:
persist_with(session) # undone when the fixture ends (by the pytest plugin)
yield session
For anything else, persist_with(fn) saves with your function. The guide has a fixture that rolls back an outer transaction instead.
The same data alone or in the suite
The pytest plugin is on as soon as factory_bot is installed. It reseeds fake for every test and every fixture from the run's seed and the test's or fixture's id. So a test that fails in the suite fails with the same names and emails when you run it alone, in another order, or under pytest-xdist. The seed is in the header:
factory_bot: seed=0, reset_sequences=off
With pytest-randomly, its seed drives this one: each run gets new data, and --randomly-seed=N replays a run's. Sequences keep counting across tests; test isolation shows how to restart them. To turn the plugin off, run pytest -p no:factory_bot.
Learn more
The guide has the rest:
- The value rule, sequences, traits, transients and callbacks, child factories
- Associations, has-many and strategies
- Faker, gotchas and type checkers
- Organizing factories and test isolation
- Recipes for Django, SQLAlchemy and checking every factory
- Error messages
Inspired by thoughtbot's factory_bot for Ruby.
Metadata
Release files for factory-bot 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| factory_bot-0.1.0.tar.gz | 52.2 kB | With provenance | Details for factory_bot-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| factory_bot-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for factory_bot-0.1.0-py3-none-any.whl |
Total release size: 72.9 kB
Release files / factory_bot-0.1.0.tar.gz
| Download URL | factory_bot-0.1.0.tar.gz |
|---|---|
| Size | 52.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6fc0643a3866158c5f4e436fc59215d52f6629efca4d85494a4802fe4ac538de
|
|
BLAKE2b-256 checksum How to use checksums |
2524a6b29d6d046b15dd46869af9d2f9576b0f698ef43fa9870041c0e25e3b24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / factory_bot-0.1.0-py3-none-any.whl
| Download URL | factory_bot-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a3f11a394dcc97f0e0e774b72dc4a6e0b82843eae8446f2018b6cd890f0ca687
|
|
BLAKE2b-256 checksum How to use checksums |
44e6206b43a10124b86247531b64736a0cd89f0128d506aafef86ca08c3956fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for factory-bot 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for factory_bot-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.