

PyTest vá além do teste unitário
Bem-vindos! Neste tutorial, exploraremos o mundo do Pytest, uma ferramenta poderosa para testes automatizados em Python.
Python Norte 2024
@vaniltonpinheiro



Quem sou?






Cadastre-se para vagas

Agenda
- O que precisa saber de Pytest
- Reaproveite o seu trabalho
- Expandindo o Pytest
- Conclusões e Boas Práticas

O que precisa saber de

o que é?
O Pytest é um framework de teste para Python, conhecido por sua simplicidade e flexibilidade. Sua estrutura intuitiva facilita a criação de testes, e sua ampla gama de recursos permite testar diferentes aspectos do código, desde funções individuais até integrações complexas.



Benefícios






Antes de tudo...
Pytest requer: Python 3.8+
Instalação: pip install pytest


Requisito para teste
class ContaBancaria:
def __int__(self, saldo_inicial=0):
self.saldo = saldo_inicial
def depositar(self, valor):
limite_deposito = 5000
if valor <= 0:
raise ValueError("O valor do depósito deve ser positivo.")
if valor > limite_deposito:
raise ValueError(f"O valor máximo para o depósito é {limite_deposito}.")
self.saldo += valor
return self.saldo

Prática



Teste unitário
import pytest
from banco import ContaBancaria
def test_deposito_valido():
conta = ContaBancaria()
conta.saldo = 100
saldo_atualizado = conta.depositar(50)
assert saldo_atualizado == 150
Reaproveite o seu trabalho

Fixtures: Reutilização de Código






Preparo de Ambientes
Fixtures permitem a inicialização de recursos, como conexões com bancos de dados, antes de cada teste.
Reutilização de Código
A reutilização de código através de fixtures garante consistência e simplifica a escrita de testes.
Melhoria Legibilidade
Organiza o código de teste, separando a lógica de setup e a lógica de teste propriamente dita.


Fixture
import pytest
class Music:
def __init__(self, nome):
self.nome = nome
def __eq__(self, outra):
return self.nome == outra.nome
class TestMusic:
@pytest.fixture
def minha_musica(self):
return Music("Black")
@pytest.fixture
def playlist(minha_musica):
return [Music("Numb"), minha_musica]
def test_minha_musica_na_playlist(self, playlist):
assert Music('Numb') in playlistParametrização: Testando Várias Entradas






Teste parametrizado
def deposito_values():
return [(100, 50, 150), (0, 5000, 5000), (0, 1, 1)]
@pytest.mark.parametrize("saldo, entrada, expectativa", deposito_values())
def test_deposito_valido_parametrizado(saldo, entrada, expectativa, setUp):
conta = setUp
conta.saldo = saldo
saldo_atualizado = conta.depositar(entrada)
assert saldo_atualizado == expectativaMarkers: Agrupando e Categorizando Testes






Marcadores
#pytest.ini
[pytest]
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
critical: marks tests as critical

Executando testes marcados
# Executando uma categoria
pytest -m "slow"
# Executando teste de duas categorias
pytest -m "slow or parametrize"
# Executando teste que atendam apenas todas categorias definidas
pytest -m "slow and parametrize"
# Executando por exclusão
pytest -m "not slow"
Expandindo o Pytest



Para Cobertura e Paralelismo
Instalação: pip install pytest-cov
pip install pytest-xdist


Cobertura de Teste
# Teste via CLI
pytest --cov=.
# Execução e resultado em HTML
pytest --cov=. --cov-report html

Testes em paralelo
# Execução em paralela
#Com -n auto, o pytest-xdist usará quantos núcleos físicos da CPU existirem em seu computador.
pytest -n auto
# Execução definindo os núcleos
pytest -n 2 

Para Performance
Instalação: pip install pytest-benchmark
pip install pygal


Testes de Performance - Padrão
def test_deposito_valido_bench(self, setUp, benchmark):
conta = setUp
conta.saldo = 100
saldo_atualizado = benchmark.pedantic(conta.depositar, args=(50,), iterations=50, rounds=100)
assert saldo_atualizado > 150# Executando o teste
pytest --benchmark-only test_banco.py


Testes de Performance - Definindo Iterações
# Exemplo CLI
pytest --benchmark-only --benchmark-min-rounds=10
# Exemplo script
def test_deposito_valido_bench(self, setUp, benchmark):
conta = setUp
conta.saldo = 100
saldo_atualizado = benchmark.pedantic(conta.depositar, args=(50,), iterations=50, rounds=100)
assert saldo_atualizado > 150# Salvando o resultado da execução
pytest --benchmark-only --benchmark-save=result_bench
# Comparar a última execução com a atual
pytest --benchmark-compare 

Testes de Performance - Resultado
# Exemplo script
def test_deposito_valido_bench(self, setUp, benchmark):
conta = setUp
conta.saldo = 100
saldo_atualizado = benchmark.pedantic(conta.depositar, args=(50,), iterations=50, rounds=100)
assert saldo_atualizado > 150# Gerando o resultado HTML
pytest-benchmark compare --histogram result_bench

Para Funcional
Instalação: pip install pytest-playwright
playwright install chromium


Testes Funcional
pip install --upgrade pip
pip install playwright
playwright install# Gerando o resultado HTML
pytest-benchmark compare --histogram result_bench

Reportando resultados
Instalação: pip install pytest-html


Relatório de Testes
# Resultado dos testes em HTML
pytest --html=report.htmlOutras integrações






Integrações com CI/CD



Conclusões e Boas Práticas




Referências
- https://pypi.org/project/pytest-benchmark/
- https://docs.pytest.org/en/stable/getting-started.html
- https://pytest-html.readthedocs.io/en/latest/
- https://playwright.dev/python/docs/test-runners


PyTest vá além do teste unitário
Bem-vindos! Neste tutorial, exploraremos o mundo do Pytest, uma ferramenta poderosa para testes automatizados em Python.
Python Norte 2024
PyTest vá além do teste unitário
By Vanilton Pinheiro
PyTest vá além do teste unitário
Neste tutorial, exploraremos o mundo do Pytest, uma ferramenta poderosa para testes automatizados em Python.
- 240