FactoryBoy / factory_boy

A test fixtures replacement for Python
https://factoryboy.readthedocs.io/
MIT License
3.5k stars 394 forks source link

Difference factory_boy vs model bakery? #739

Open lggwettmann opened 4 years ago

lggwettmann commented 4 years ago

Hey guys,

why would I use factory boy over model bakery or vice versa? Could anyone shed some light on the similarities and differences? I tried to look it up but really can't anything in either docs and also not on the internets.

Your help is greatly appreciated.

rbarrois commented 4 years ago

Hi,

factory-boy helps you provide a recipe for creating realistic objects. For instance, if your model is:

class User:
    fullname: str
    shortname: str
    email: str
    password: str
    is_admin: bool

You could write a factory as follow:

class UserFactory(factory.Factory):
    class Meta:
        model = User
    fullname = factory.Faker('name')
    shortname = factory.Faker('first_name')
    email = factory.Faker('email')
    password = factory.Faker('pystr')
    is_admin = False

factory_boy takes the position that "Explicit is better than implicit", and encourages you to provide a domain-relevant definition of fields (for instance, having a realistic-looking full name instead of a random string of digits). This focus pushed us to add many declarations and helpers to help you define clearly the relationships between your models, including adding your own custom logic if needed - maybe hooking in some of your actual business code.

You could, for instance, derive a AdminUserFactory() from the simpler UserFactory() above, which would toggle the is_admin flag and add the user to a set of groups, and maybe add a "user promotion" record somewhere.

Moreover, factory_boy isn't limited to Django: you could use it to craft HTTP requests or JSON payloads.

If I had to sum up the difference:

karina-klinkeviciute commented 3 years ago

As I understand, Faker can be used with Model Bakery too? For those fields where we do need realistic values, we can use it, right?

1oglop1 commented 3 years ago

@karina-klinkeviciute From 10 minutes look at model_bakery I think that factory boy API is much more intuitive to use.

@rbarrois Speaking of intuitive API I do not like the Faker wrapper provided by factory boy because it's hiding object attributes behind strings and once faker will finally provide stubs IDEs will be able to whisper the methods provided. eg. Faker().n -ctrl+space> Faker().name() - You are most likely not able to achieve something like this with plaintext arguments thouhg.

rbarrois commented 3 years ago

@1oglop1 indeed, I'm not fully satisfied with the factory.Faker wrapper. However, since Faker allows users to dynamically register providers, it's perfectly possible to have extra callables that aren't listed on Faker's stubs... This needs further thought!