factory_boy
A versatile test fixtures replacement for Python, providing declarative factories for building complex test objects.
Repository Health
Technical Analysis
factory_boy is a fixtures replacement library for Python tests, inspired by Ruby’s factory_bot. Instead of maintaining static, brittle test fixtures, you declare factories that describe how to build complex objects, then override only the fields that matter for a given test.
It integrates directly with Django, SQLAlchemy, MongoEngine, and Mogo through dedicated factory base classes, and generates realistic random data via the Faker library. Multiple build strategies (build, create, stub) let the same factory produce unsaved instances, persisted records, or lightweight stub objects, while sequences, lazy attributes, and sub-factories model relationships and computed fields without duplicating setup code across tests.
What You Get
- Declarative
factory.Factoryclasses with class-level attribute declarations instead of hand-maintained fixture files - Built-in ORM integrations for Django (
DjangoModelFactory), SQLAlchemy (SQLAlchemyModelFactory), MongoEngine, and Mogo - Faker-backed random data generation via
factory.Fakerfor realistic, non-repetitive test values - Multiple instantiation strategies (
build,create,stub) and batch helpers (build_batch,create_batch) for one-off or bulk object creation - Sequence,
LazyAttribute,LazyFunction, andSubFactorydeclarations for computed fields and related-object graphs - Reproducible randomness via
factory.random.reseed_randomfor deterministic test runs
Common Use Cases
- Replacing static JSON/YAML fixture files with factories that stay in sync with model changes
- Generating related object graphs (e.g. an order with a customer and shipping address) in one factory call
- Building realistic demo/seed data for a Django or SQLAlchemy application using Faker-backed fields
- Testing edge cases by overriding only the attributes relevant to a specific scenario
- Producing large batches of test objects for load or pagination tests via
create_batch
Under The Hood
Architecture
factory.base defines a FactoryMetaClass controlling class creation via __new__/__call__, collecting Meta options through a FactoryOptions/OptionDefault descriptor pattern (contribute_to_class) reminiscent of Django’s own model metaclass. factory.declarations implements a large family of Declaration subclasses (LazyAttribute, SubFactory, Sequence, Trait, PostGeneration, Transformer) that are evaluated by factory.builder’s DeclarationSet/resolver during instance construction, in a two-phase pipeline: pre-declarations are resolved into a LazyStub, then a strategy-specific generation step calls create/build. ORM-specific subclasses (django.py, alchemy.py, mongoengine.py, mogo.py) override _create/_get_or_create hooks so the same declarative core plugs into different persistence backends without changing declaration syntax; because every ORM adapter inherits _meta resolution and strategy dispatch from BaseFactory, changes to the metaclass contract in base.py ripple across all of them.
Tech Stack Pure Python library supporting Python 3.8+ per setup.cfg, with CI exercising 3.9 through 3.13 plus PyPy, and a single runtime dependency on Faker. Development-only extras add Django, SQLAlchemy, mongoengine, mongomock, Pillow, coverage, flake8, isort, mypy, tox, and zest.releaser; docs are built with Sphinx, sphinx_rtd_theme, and sphinxcontrib-spelling. The package is distributed as a universal wheel via plain setuptools/setup.cfg rather than a modern build backend. The tox matrix and GitHub Actions workflows (test.yml, check.yml) run the suite across multiple Python versions and Django/SQLAlchemy/mongoengine combinations.
Code Quality
The test suite spans thousands of lines across dedicated files per surface (test_base, test_declarations, test_django, test_alchemy, test_mongoengine, test_fuzzy, test_typing, test_dev_experience), plus fixture Django/SQLAlchemy apps for integration-style tests, run through the standard library’s unittest via make test. mypy is part of the tox lint environment and the package ships a py.typed marker, so the public API is expected to type-check for consumers. flake8 and isort enforce style and run in a dedicated CI job alongside doc and example builds. errors.py defines a small, consistently used typed exception hierarchy rather than swallowing failures silently.
API Design
The public API is a small, memorable vocabulary (Factory, SubFactory, Sequence, Faker, LazyAttribute, Trait) modeled closely on Ruby’s factory_bot, so the concepts transfer directly for developers coming from that ecosystem. Getting started requires only a class Meta: model = ... block with no registration step or config file, and the same factory works across build/create/stub without redefinition. Public entry points carry docstrings and type hints, and the README documents the full surface with runnable examples. The main ergonomic cost is discoverability: after many years of growth the declaration vocabulary (Trait, Maybe, Transformer, RelatedFactoryList) is extensive, so newcomers typically start with a handful of primitives and grow into the rest.
Used by 2 apps in this directory
argilla
AI Development · Data Engineering
Collaborate on high-quality AI training data with a self-hosted annotation platform built for LLMs, NLP, and multimodal models.
Docs
File Storage · CMS
Open-source collaborative knowledge platform with real-time editing, AI writing tools, and full self-hosting control — built by the French and German governments.