20 de setembro de 2021

Pytest: Pequeno manual para o dia a dia - Fixtures

Depois que comecei a programar em Python no dia a dia eu me deparei com uma das ferramentas mais legais de teste que conheci, o Pytest. Por padrão o Python já vem com uma ferramenta de testes chamada Unittest, que é muito boa e funcional, porém como ela foi criada junto com o Python algumas arestas dela ficaram soltas, principalmente por não utilizar toda a potência que a própria linguagem oferece. Aqui eu vou deixar algumas coisas muito interessantes que uso no meu dia a dia e como podem servir principalmente como um guia rápido do Pytest.

O Pytest é compatível com o unittest

Caso você tenha algum receio em migrar do Unittest para o Pytest a primeira novidade é que ele é compatível com os testes escritos em Unittest, assim você não perde em nada ao tentar executar o teste abaixo:
Pytest executando cenários de teste do unittest
Com isso a migração para o Pytest é mais simples caso seu projeto já utilize o unittest como framework de teste.

Fixtures: objetos reutilizáveis e setUp() e tearDown()

O Pytest consta com um mecanismo de criação de dependências de testes chamado fixtures. Basicamente uma fixture é um "acessório" que  você utilizará em um ou mais testes que será injetado no seu teste a partir de uma assinatura de função. Um exemplo simples de como funciona é o seguinte:
 
Perceba que apenas com a assinatura da função tendo o mesmo nome da fixture criada ela já será automaticamente repassada para a função de teste. Mas isso é só o começo das fixtures, perceba que no unittest utilizamos muito os métodos setUp() e tearDown() para definir tudo que precisa rodar antes e depois dos nossos testes (por exemplo criar e limpar registros em um banco de dados ou cache), mas como os testes do Pytest não precisam estar contidos em classes como podemos ter um comportamento similar? Novamente as fixtures podem nos ajudar com isto!
 
Quando a fixture é um generator (funções em Python com o yield no corpo) o Pytest lida com ela de uma forma diferentes, vejamos o exemplo abaixo:
Executando o teste passando a flag -s ao final para imprimir os prints() podemos ver como foi executado:
 
Veja que primeiro foi executado o código antes do yield, depois o código da função de testes e por último o código que veio depois do yield. Quem fez todo esse gerenciamento foi o próprio Pytest, que identificou que a função é um generator possibilitando controlarmos que códigos executam antes ou depois do cenário de teste em questão.

Para elevar o nível da reutilização das fixtures é possível armazena-las em arquivos especiais que são lidos automaticamente, para isso basta armazenar a fixture em um arquivo conftest.py. O Pytest irá ler esse arquivo e disponibilizar as fixtures em todos os testes na mesma hierarquia ou nos pacotes abaixo:

Esta é um pequeno começo sobre o poder do Pytest, ainda há muito o que falar sobre ele, principalmente alguns plugins que permitem executar casos de teste ainda mais complexos.

Nenhum comentário:

Postar um comentário