simplificando_a_criacao_de_testes_com_model_bakery_capa
Higor Vinicius

Higor Vinicius

23 Mai 2023 4 min read

Simplificando a criação testes com model-bakery

Criar fixtures para testes no Django de forma manual é algo muito trabalhoso e chato. E escrever os testes em si nem sempre é uma tarefa agradável, especialmente quando é preciso criar fixtures para nos auxiliar nos testes, gerar e atualizar o dump.json se torna muito custoso. O model-bakery, com sua API simples e robusta, pode criar muitos objetos em uma única linha de código.

Primeiramente, vamos apresentar o arquivo de models com o qual vamos trabalhar:

Baseando nesses modelos, vamos criar um exemplo de teste usando fixtures. Vamos gerar essa fixtures com o resultado do comando manage.py dumpdata que gerou um arquivo com dados de 206 produtos cadastrados.

Nesse caso específico, o arquivo load_products.json pode ser facilmente substituído por uma linha de código usando model-bakery.

Como podemos ver, geramos duzentos objetos em apenas uma linha de código. Observando um pouco essa linha de código, temos a model Product, em seguida o atributo _quantity com a quantidade de objetos que queremos criar. Mais a frente veremos como podemos combinar o atributo _quantity com outro atributo muito legal chamado seq.

Model Relationships

Outro ponto que gosto bastante é a simplicidade com a qual o bakery trabalha com relacionamento, seja ele many-to-many ou one-to-one, vejamos alguns exemplos:

Por padrão, o model-bakery não cria instâncias relacionadas automaticamente m2m, você precisa passar o atributo make_m2m=True. Caso você queira algo mais explícito, você pode fazer da seguinte forma:

Pytest & model-bakery

Trabalhando em projetos legados, é normal você se deparar com o uso de duas ou mais libs, para a escrita de testes, como pytest e model-bakery. Na minha opinião é um casamento perfeito. No pytest é comum ver o uso do decorador @pytest.fixture centralizado no arquivo chamado conftest.py ou diretamente no seu arquivo de teste. No model-bakery usamos oRecipes para evitar a duplicação de código, e caso você não esteja confortável com dados gerados randomicamente, o uso de Recipes é uma ótima ideia. O exemplo a seguir mostra um caso usando ambas as bibliotecas:

Você ainda pode combinar o uso de @pytest.fixture e model-bakery da seguinte forma:

Esse foi um exemplo muito simples apenas para demonstrar o quão tranquilo é associar essas duas libs, deixando seus testes cada vez mais simples de entender, com baixa complexidade e fácil manutenção.

Criando objetos sem persistir no banco

Em algum momento, você vai se deparar com sua build de teste ficando cada dia mais lenta, principalmente se seus testes precisarem criar muitos objetos. Para isso, podemos contar com o método prepare. O prepare funciona bem parecido com make, podendo se usufruir de todos os atributos, sem precisar persistir na sua base de dados.

Caso você precise persistir apenas as instâncias relacionadas em PurchaseHistory, pode usar o _save_related, veja no exemplo abaixo como seria isso:

Como vimos, podemos perceber na prática como é interessante o uso do model-bakery, como o seu uso com diferentes bibliotecas (como o Pytest) facilita a adição de recursos e ainda simplifica os testes, além da API enxuta e relativamente intuitiva. Você tem alguma dúvida ou sugestão de uso? Deixe sua mensagem nos comentários e a gente se vê na próxima!

Referencias:

Model Bakery: Smart fixtures for better tests — Model Bakery 1.11.0 documentation

GitHub - model-bakers/model_bakery: Object factory for Django

Escrevendo testes melhores com Model-bakery - Higor Monteiro [PyBR2022]