Factory Boy

February 18, 2014

I develop a Django application which has been rolling for three years now. I barely have a 40% of code coverage through tests, which is pretty low. When writing tests, the most annoying thing in my opinion is to get a dataset to work with. Using fixtures is the direct way, but it’s not that easy to write them by hand, also it’s difficult to get them in sync with migrations. But we have factory boy to save the day.

I first met factory boy in

As soon as I could, I gave it a try.

I created some Factories

class RolFactory(factory.django.DjangoModelFactory):

    name = factory.Sequence(lambda n: u"rol%s" % n)
    description = u"A test rol"

class CacheFactory(factory.django.DjangoModelFactory):
    FACTORY_FOR = Cache

    id = factory.Sequence(lambda n: n)
    code = factory.Sequence(int)
    document_number = factory.Sequence(lambda n: u"%s" % n)
    name = u"John"
    surname = u"Doe"

You just need to include those attributes that need default values. In my case I included all the attributes not nullable or without a default value. So now I can start using the factories. One interesting thing is that you can use attributes not defined in factory class, but existing in model.

So lets use them a bit

    r = RolFactory.create(name="alumno")

It’s that simple. If my models are modified, then I may need to modify the factory class, but it would be just in one place.

As factories are classes, you can import and use them where needed, so I guess I may write them under every app directory, not sure if in tests.py file or in a separate file, but that would be another story.