Upgrade to Pro — share decks privately, control downloads, hide ads and more …

factory_boy: testing like a pro. DjangoCon US 2022

Camila Maia
October 13, 2022

factory_boy: testing like a pro. DjangoCon US 2022

Camila Maia

October 13, 2022
Tweet

More Decks by Camila Maia

Other Decks in Technology

Transcript

  1. @cmaiacd Brazilian living in Berlin Bachelor of Computer Information System

    Coding since 2010 👵 Python 🐍 and Ruby 💎 Open Source and Community ❤ Conferences Backend Developer @ SoundCloud
  2. @cmaiacd First GitHub profile to be accepted for the GitHub

    Sponsors program in Brazil 󰎙 Quem sou eu?
  3. @cmaiacd • It is a fixtures replacement • Based on

    factory_bot (Thoughtbot) • First version: Django only • Nowadays: framework-independent • Unittest, Pytest...
  4. @cmaiacd ❌ Fixtures: exhaustive test setup with every possible combination

    of corner cases ✅ Factories: objects customized for the current test, while only declaring the test-specific fields
  5. @cmaiacd It offers many tools that help with the creation

    of the tests: • Sequence • Faker • Fuzzy attributes • LazyFunction • LazyAttribute • Inheritance • Params • Traits • Strategies • RelatedFactory/SubFactory
  6. @cmaiacd Model - Poll Poll Question Choice n:1 pub_date :

    DateTimeField premium : BooleanField author : CharField question_text : CharField language : CharField choice_text : CharField votes : IntegerField 1:1
  7. @cmaiacd • +3 years • Django Monolith • +230 tables

    • +2200 relevant files • +75k relevant lines My experience
  8. @cmaiacd Bad factories are like viruses • Factories can get

    too tied • Implicit errors might happen • Factory usage involves a lot of copy/paste with small changes • A poorly designed factory might affect many tests • The tests are created in a way to fit the factory (factory-oriented testing) • Developers bump into the same issue again and again • The same hack has to be done several times
  9. @cmaiacd • If a default value is changed, all tests

    that depend on it will break • The setup of a test should contain all the logic to ensure it will always pass • Explicit better than implicit
  10. @cmaiacd If the field is nullable (null=True) the attribute should

    be under a trait and not as a default value
  11. @cmaiacd • If we want to have an author, we

    can use PollFactory(with_author=True) now • When are we going to remember to test the case PollFactory(author=None)? • We should not assume there is an author when DB actually allows to not have it.
  12. @cmaiacd BUILD STRATEGY ======================== 14 passed in 1.76 seconds =========================

    CREATE STRATEGY ======================== 14 passed in 3.26 seconds =========================
  13. @cmaiacd 5. IF FK IS IN THE TABLE: SUBFACTOR IF

    FK IS IN THE OTHER TABLE: RELATEDFACTORY + TRAIT
  14. @cmaiacd • SubFactory: builds/creates the SubFactory during the process of

    creation of the main factory • RelatedFactory: builds/creates the RelatedFactory after creating the main factory
  15. @cmaiacd • Many tests depending on the same factory/fixture •

    Tends to inflate the factory/fixture • Hard to maintain • Change a factory/fixture => tons of tests breaking • Fixture/Factory-oriented testing
  16. @cmaiacd 1. Factories should represent their models 2. Do not

    rely on defaults from factories 3. Factories should contain only the required data 4. Build over create 5. If FK is in the table: SubFactor If FK is in the other table: RelatedFactory + trait 6. Avoid sharing factories or fixtures among different files 7. Use fixtures to wrap factories to avoid duplication Review