Slide 1

Slide 1 text

FACTORYBOY Creating data for unit tests in an easy way @andreagrandi Andrea Grandi

Slide 2

Slide 2 text

HOW TO GET DATA FOR UNIT TESTS • Using production DB – Do NOT do it! • Using fixtures – Not very handy • Using the ORM way to create data – It's ok but it can be long, repetitive and increase the lines of code in unittests • Or ...

Slide 3

Slide 3 text

FACTORYBOY • Support for multiple build strategies (unsaved/saved instances: build() and create() ) • Powerful helpers for common cases (sequences, sub-factories, reverse dependencies, circular factories, ...) • Support for various ORMs (currently Django, Mogo, MongoEngine, SQLAlchemy) • Python >= 2.6 and PyPy are supported

Slide 4

Slide 4 text

FACTORYBOY: DEFINING FACTORIES • subclass factory.Factory • add a class Meta block • set the model attribute of the Meta block • add default values

Slide 5

Slide 5 text

FACTORYBOY: DEFINING FACTORIES (EXAMPLE) import factory from . import models class CustomerFactory(factory.Factory): class Meta: model = models.Customer first_name = 'John' last_name = 'Doe' admin = False

Slide 6

Slide 6 text

FACTORYBOY: USING FACTORIES # Returns a Customer instance that's not saved customer = CustomerFactory.build() # Returns a saved Customer instance customer = CustomerFactory.create() # Returns a dict of attributes that can be used to # build a Customer instance attributes = CustomerFactory.attributes()

Slide 7

Slide 7 text

YOU CAN ALWAYS OVERRIDE # Build a Customer instance and override first_name >>> customer = CustomerFactory.build(first_name='Joe') >>> customer.first_name "Joe"

Slide 8

Slide 8 text

Lazy Attributes class CustomerFactory(factory.Factory): class Meta: model = models.Customer first_name = 'Joe' last_name = 'Blow' email = factory.LazyAttribute( lambda a:'{0}.{1}@example.com'.format( a.first_name, a.last_name).lower())

Slide 9

Slide 9 text

Sequences class CustomerFactory(factory.Factory): class Meta: model = models.Customer email = factory.Sequence( lambda n: person{0}@example.com'.format(n)) >>> CustomerFactory().email '[email protected]' >>> CustomerFactory().email '[email protected]'

Slide 10

Slide 10 text

Relations class PostFactory(factory.Factory): class Meta: model = models.Post author = factory.SubFactory(CustomerFactory)

Slide 11

Slide 11 text

Create Strategy # Builds and saves a Customer and a Post >>> post = PostFactory.create() >>> post.id is None # Post has been 'saved' False >>> post.author.id is None # post.author has been saved False

Slide 12

Slide 12 text

Build Strategy # Builds but does not save a Customer, and then builds # but does not save a Post >>> post = PostFactory.build() >>> post.id is None True >>> post.author.id is None True

Slide 13

Slide 13 text

ORM Support • Django, with DjangoModelFactory • Mogo, with MogoFactory • MongoEngine, with MongoEngineFactory • SQLAlchemy, with SQLAlchemyModelFactory

Slide 14

Slide 14 text

References All the code examples and documentation have been taken from the official project website, available at http://factoryboy.readthedocs.org

Slide 15

Slide 15 text

Thanks! Twitter: @andreagrandi