Snippet for Fun

Flask database test fixture generation with factory_boy

Posted at — Apr 10, 2021


It’s tedious to generate test fixtures by hand, to allow faster iteration, we can employ factory_boy to generate these fixtures automatically for our Python project. What even better is, factory_boy has builtin support for well known ORM libraries, such as SQLALchemy and Django.


Suppose we are building a service that records famous quotes. In this service, we define a Quote model for quote entries like this:

# in

db = SQLAlchemy()

class Quote(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    author = db.Column(db.String(100), nullable=False)
    message = db.Column(db.Text)

Then in the test side (for common testing setup, see Flask database test setup with py.test), we can define a factory for this model:

# in test/

import factory

from app import db, Quote

class QuoteFactory(factory.alchemy.SQLAlchemyModelFactory):

    class Meta:
        model = Quote
        sqlalchemy_session = db.session

    author = factory.Faker('name')
    message = factory.Faker('text')

Now, we can consume this factory in various places:

Using in REPL

(venv) $ flask shell
App: app [production]
>>> from app import Quote
>>> from test.factory import QuoteFactory
>>> quote =
>>> assert isinstance(quote, Quote)
>>> print(
Thomas Miller
>>> print(quote.message)
Doctor game enough with.
Responsibility yourself themselves information. Single support east.
Operation night line parent take act new. She race activity. Air in fish prevent behind.

Using in tests

During the test, we can use XXXFactory.create to create an instance and add it to current test db session:

def test_create_one_quote(db):
    quote = QuoteFactory.create()
    assert is not None
    assert quote.message

We can also override the value for one or multiple fields, by specifying the field name in create call:

def test_create_many_quotes(db):
    expected_author = 'Louis Armstrong'
    quotes = QuoteFactory.create_batch(100, author=expected_author)
    for quote in quotes:
        assert is not None
        assert == expected_author
        assert quote.message


With the help of factory_boy, we can generate a large collection of test fixtures without much effort.

A full example of code can be check out from the GitHub repo.