# Introduction

The purpose of factory_boy is to provide a default way of getting a new instance, while still being able to override some fields on a per-call basis.

Note

This section will drive you through an overview of factory_boy’s feature. New users are advised to spend a few minutes browsing through this list of useful helpers.

Users looking for quick helpers may take a look at Common recipes, while those needing detailed documentation will be interested in the Reference section.

## Basic usage

Factories declare a set of attributes used to instantiate an object, whose class is defined in the `class Meta`’s `model` attribute:

- Subclass `factory.Factory` (or a more suitable subclass)

- Add a `class Meta:` block

- Set its `model` attribute to the target class

- Add defaults for keyword args to pass to the associated class’ `__init__` method

    import factory
    from . import base

    class UserFactory(factory.Factory):
        class Meta:
            model = base.User

        firstname = "John"
        lastname = "Doe"

You may now get `base.User` instances trivially:

    >>> john = UserFactory()
    <User: John Doe>

It is also possible to override the defined attributes by passing keyword arguments to the factory:

    >>> jack = UserFactory(firstname="Jack")
    <User: Jack Doe>

A given class may be associated to many `Factory` subclasses:

    class EnglishUserFactory(factory.Factory):
        class Meta:
            model = base.User

        firstname = "John"
        lastname = "Doe"
        lang = 'en'

    class FrenchUserFactory(factory.Factory):
        class Meta:
            model = base.User

        firstname = "Jean"
        lastname = "Dupont"
        lang = 'fr'

    >>> EnglishUserFactory()
    <User: John Doe (en)>
    >>> FrenchUserFactory()
    <User: Jean Dupont (fr)>

## Sequences

When a field has a unique key, each object generated by the factory should have a different value for that field. This is achieved with the `Sequence` declaration:

    class UserFactory(factory.Factory):
        class Meta:
            model = models.User

        username = factory.Sequence(lambda n: 'user%d' % n)

    >>> # The sequence counter starts at 0 by default
    >>> UserFactory()
    <User: user0>
    >>> UserFactory()
    <User: user1>

    >>> # A value can be provided for a sequence-driven field
    >>> # but this still increments the sequence counter
    >>> UserFactory(username="ada.lovelace")
    <User: ada.lovelace>
    >>> UserFactory()
    <User: user3>

Note

For more complex situations, you may also use the `@factory.sequence` decorator (note that `self` is not added as first parameter):

>     class UserFactory(factory.Factory):
>         class Meta:
>             model = models.User

>         @factory.sequence
>         def username(n):
>             return 'user%d' % n

To set or reset the sequence counter see Forcing a sequence counter.

## LazyFunction

In simple cases, calling a function is enough to compute the value. If that function doesn’t depend on the object being built, use `LazyFunction` to call that function; it should receive a function taking no argument and returning the value for the field:

    class LogFactory(factory.Factory):
        class Meta:
            model = models.Log

        timestamp = factory.LazyFunction(datetime.now)

    >>> LogFactory()
    <Log: log at 2016-02-12 17:02:34>

    >>> # The LazyFunction can be overridden
    >>> LogFactory(timestamp=now - timedelta(days=1))
    <Log: log at 2016-02-11 17:02:34>

Note

For complex cases when you happen to write a specific function, the `@factory.lazy_attribute` decorator should be more appropriate.

## LazyAttribute

Some fields may be deduced from others, for instance the email based on the username. The `LazyAttribute` handles such cases: it should receive a function taking the object being built and returning the value for the field:

    class UserFactory(factory.Factory):
        class Meta:
            model = models.User

        username = factory.Sequence(lambda n: 'user%d' % n)
        email = factory.LazyAttribute(lambda obj: '%s@example.com' % obj.username)

    >>> UserFactory()
    <User: user0 (user0@example.com)>

    >>> # The LazyAttribute handles overridden fields
    >>> UserFactory(username='john')
    <User: john (john@example.com)>

    >>> # They can be directly overridden as well
    >>> UserFactory(email='doe@example.com')
    <User: user2 (doe@example.com)>

Note

As for `Sequence`, a `@factory.lazy_attribute` decorator is available:

    class UserFactory(factory.Factory):
        class Meta:
            model = models.User

        username = factory.Sequence(lambda n: 'user%d' % n)

        @factory.lazy_attribute
        def email(self):
            return '%s@example.com' % self.username

## Inheritance

Once a “base” factory has been defined for a given class, alternate versions can be easily defined through subclassing.

The subclassed `Factory` will inherit all declarations from its parent, and update them with its own declarations:

    class UserFactory(factory.Factory):
        class Meta:
            model = base.User

        firstname = "John"
        lastname = "Doe"
        group = 'users'

    class AdminFactory(UserFactory):
        admin = True
        group = 'admins'

    >>> user = UserFactory()
    >>> user
    <User: John Doe>
    >>> user.group
    'users'

    >>> admin = AdminFactory()
    >>> admin
    <User: John Doe (admin)>
    >>> admin.group  # The AdminFactory field has overridden the base field
    'admins'

Any argument of all factories in the chain can easily be overridden:

    >>> super_admin = AdminFactory(group='superadmins', lastname="Lennon")
    >>> super_admin
    <User: John Lennon (admin)>
    >>> super_admin.group  # Overridden at call time
    'superadmins'

## Non-kwarg arguments

Some classes take a few, non-kwarg arguments first.

This is handled by the `inline_args` attribute:

    class MyFactory(factory.Factory):
        class Meta:
            model = MyClass
            inline_args = ('x', 'y')

        x = 1
        y = 2
        z = 3

    >>> MyFactory(y=4)
    <MyClass(1, 4, z=3)>

## Altering a factory’s behavior: parameters and traits

Some classes are better described with a few, simple parameters, that aren’t fields on the actual model. In that case, use a `Params` declaration:

    class RentalFactory(factory.Factory):
        class Meta:
            model = Rental

        begin = factory.fuzzy.FuzzyDate(start_date=datetime.date(2000, 1, 1))
        end = factory.LazyAttribute(lambda o: o.begin + o.duration)

        class Params:
            duration = 12

    >>> RentalFactory(duration=0)
    <Rental: 2012-03-03 -> 2012-03-03>
    >>> RentalFactory(duration=10)
    <Rental: 2008-12-16 -> 2012-12-26>

When many fields should be updated based on a flag, use `Traits` instead:

    class OrderFactory(factory.Factory):
        status = 'pending'
        shipped_by = None
        shipped_on = None

        class Meta:
            model = Order

        class Params:
            shipped = factory.Trait(
                status='shipped',
                shipped_by=factory.SubFactory(EmployeeFactory),
                shipped_on=factory.LazyFunction(datetime.date.today),
            )

A trait is toggled by a single boolean value:

    >>> OrderFactory()
    <Order: pending>
    >>> OrderFactory(shipped=True)
    <Order: shipped by John Doe on 2016-04-02>

## Strategies

All factories support two built-in strategies:

- `build` provides a local object

- `create` instantiates a local object, and saves it to the database.

Note

For 1.X versions, the `create` will actually call `AssociatedClass.objects.create`, as for a Django model.

Starting from 2.0, `factory.Factory.create()` simply calls `AssociatedClass(**kwargs)`. You should use `DjangoModelFactory` for Django models.

When a `Factory` includes related fields (`SubFactory`, `RelatedFactory`), the parent’s strategy will be pushed onto related factories.

Calling a `Factory` subclass will provide an object through the default strategy:

    class MyFactory(factory.Factory):
        class Meta:
            model = MyClass

    >>> MyFactory.create()
    <MyFactory: X (saved)>

    >>> MyFactory.build()
    <MyFactory: X (unsaved)>

    >>> MyFactory()  # equivalent to MyFactory.create()
    <MyClass: X (saved)>

The default strategy can be changed by setting the `class Meta` `strategy` attribute.