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 app.py 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/factory.py 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:
(venv) $ flask shell App: app [production] ... >>> from app import Quote >>> from test.factory import QuoteFactory >>> quote = QuoteFactory.build() >>> assert isinstance(quote, Quote) >>> print(quote.author) 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.
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() db.session.commit() assert quote.id is not None assert quote.author 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) db.session.commit() for quote in quotes: assert quote.id is not None assert quote.author == 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.