A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby
npx @tessl/cli install tessl/pypi-factory-boy@2.12.0A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby. Factory Boy provides a comprehensive library for generating test data with customizable attributes, supporting multiple build strategies and integrating seamlessly with popular ORMs including Django, SQLAlchemy, MongoEngine, and Mogo.
pip install factory_boyimport factoryMost commonly used components:
from factory import Factory, Sequence, LazyAttribute, SubFactory, FakerORM-specific imports:
from factory.django import DjangoModelFactory
from factory.alchemy import SQLAlchemyModelFactory
from factory.mongoengine import MongoEngineFactory
from factory.mogo import MogoFactory
# Also available at module level:
from factory import DjangoModelFactory, MogoFactoryimport factory
from factory import Sequence, LazyAttribute, SubFactory, Faker
# Define a simple factory
class UserFactory(factory.Factory):
class Meta:
model = User
# Simple static value
is_active = True
# Sequence for unique values
email = Sequence(lambda n: f'user{n}@example.com')
# Lazy attribute based on other fields
username = LazyAttribute(lambda obj: obj.email.split('@')[0])
# Faker integration for realistic data
first_name = Faker('first_name')
last_name = Faker('last_name')
# Using the factory
user = UserFactory() # Creates User instance
user = UserFactory.build() # Build without persistence
user = UserFactory.create() # Create with persistence
user = UserFactory.stub() # Create stub object
# Batch operations
users = UserFactory.build_batch(5) # Create 5 users
users = UserFactory.create_batch(3, is_active=False) # Override defaults
# Custom attributes
user = UserFactory(first_name='John', is_active=False)Factory Boy follows a declarative factory pattern with three core concepts:
This design enables maintainable, reusable test data generation that replaces static fixtures with flexible, programmatic object creation across different ORMs and testing frameworks.
Essential factory classes supporting different build strategies and object types. Includes the main Factory class, dictionary and list factories, and stub-only factories.
class Factory:
def build(**kwargs): ...
def create(**kwargs): ...
def stub(**kwargs): ...
def build_batch(size, **kwargs): ...
def create_batch(size, **kwargs): ...
class DictFactory(Factory): ...
class ListFactory(Factory): ...
class StubFactory(Factory): ...
def use_strategy(strategy): ...Comprehensive declaration types for generating dynamic attribute values including sequences, lazy evaluation, faker integration, and conditional logic.
class Sequence:
def __init__(self, function): ...
class LazyAttribute:
def __init__(self, function): ...
class LazyFunction:
def __init__(self, function): ...
class Faker:
def __init__(self, provider, **kwargs): ...
class Iterator:
def __init__(self, iterator, cycle=True, getter=None): ...
class SelfAttribute:
def __init__(self, attribute_name, default=None): ...Specialized factory classes for popular ORMs providing database persistence, get-or-create behavior, and ORM-specific features.
class DjangoModelFactory(Factory): ...
class SQLAlchemyModelFactory(Factory): ...
class MongoEngineFactory(Factory): ...
class MogoFactory(Factory): ...
# Django helpers
class FileField: ...
class ImageField: ...
def mute_signals(*signals): ...Convenience functions for direct object creation, debugging tools, and declaration wrapper functions for functional programming styles.
def build(klass, **kwargs): ...
def create(klass, **kwargs): ...
def stub(klass, **kwargs): ...
def make_factory(klass, **kwargs): ...
def debug(logger='factory', stream=None): ...
# Declaration wrappers
def lazy_attribute(func): ...
def sequence(func): ...
def post_generation(func): ...Helper Functions and Utilities
BUILD_STRATEGY = 'build'
CREATE_STRATEGY = 'create'
STUB_STRATEGY = 'stub'
SPLITTER = '__' # String for splitting attribute names into subfactory paths
# Module metadata
__version__ = '2.12.0' # Current version
__author__ = 'Raphaël Barrois <raphael.barrois+fboy@polytechnique.org>'def use_strategy(new_strategy):
"""
Decorator to override default strategy for a factory class.
Args:
new_strategy (str): Strategy to use ('build', 'create', 'stub')
Returns:
Decorator function that modifies factory's default strategy
"""class FactoryError(Exception):
"""Base exception class for all factory_boy errors."""
class AssociatedClassError(FactoryError):
"""Raised when a Factory subclass lacks Meta.model."""
class UnknownStrategy(FactoryError):
"""Raised when a factory uses an unknown strategy."""
class UnsupportedStrategy(FactoryError):
"""Raised when trying to use an incompatible strategy on a Factory."""
class CyclicDefinitionError(FactoryError):
"""Raised when cyclical declaration dependencies are detected."""
class InvalidDeclarationError(FactoryError):
"""Raised when sub-declaration has no related declaration (e.g. 'foo__bar' without 'foo')."""# Strategy types
Strategy = Literal['build', 'create', 'stub']
# Declaration base class
class BaseDeclaration:
def evaluate(self, instance, step, extra): ...