Why is factory_boy superior to using the ORM directly in tests?
Asked Answered
G

1

22

I don't see why factory_boy is preferred over creating ORM/model instances directly in Django tests. And the factory_boy website does little to explain the benefits of using it.

It makes sense as an alternative to fixtures, which are difficult to manage, are slow, etc. etc.

But, why not just create model instances as needed for the tests?

If factory_boy completely replaced writing to the db, then fine, I think it'd be very useful in this case, but the the factory boy created django model instances still interact with the database.

Another potential benefit is the support for sequences, but it is not hard to create sequences / sample data without the need for factory boy.

All in all I'm seeing virtually no benefits in using factory boy, vs creating objects/model instances directly.

I hope I'm missing something glaringly obvious!

Gobetween answered 28/4, 2014 at 19:41 Comment(0)
P
27

Yes, you can prepare your test data by using django ORM directly. But there are advantages of using factories and factory_boy specifically, here are some of that I remember and use:

  • your model factories are defined in a nice, clean and readable manner:

    class CasesFactory(factory.Factory):
        FACTORY_FOR = models.Case
    
        number = factory.Sequence(lambda n: '1021-{0}'.format(n))
        create_date = datetime.datetime.now()
    
  • another benefit of this class-based approach is the ability to create SubFactories

  • also you can easily define factories for different kind of relationships: ForeignKey, reverse ForeignKey, ManyToMany (documentation)

  • neat DjangoModelFactory class
  • Sequences (as you've mentioned) helps make the data more "dynamic". Imagine handling it yourself.
  • mute_signals decorator - sometimes while testing you don't want the signal to be dispatched

Basically, factory_boy is there to avoid writing "helper" functions for generating test data. Instead, it introduces a nice and easy-to-use interface to it.

Ask yourself: why reinvent the wheel is there is a tool specifically for the job?

Also see:

Philipines answered 28/4, 2014 at 19:56 Comment(1)
Another really basic one worth adding: you can specify default values to use for your tests without having them as defaults on the actual model itself. This is great if you have Really Important Attributes that should error out if they're not explicitly supplied in the actual app (so you can't have a model default), but you don't really care about them in some of your test cases.Menon

© 2022 - 2024 — McMap. All rights reserved.