factory_boy

A versatile test fixtures replacement for Python, providing declarative factories for building complex test objects.

Library
PyPI
v3.3.3
3,805stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
43/100Fair
Development Activity0
Maintenance0
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
84/100Excellent
Architecture82
Code Quality85
Innovation78
Learning Curve90

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.Factory classes 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.Faker for 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, and SubFactory declarations for computed fields and related-object graphs
  • Reproducible randomness via factory.random.reseed_random for 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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search