Módulo 3: Validação de dados vira teste
O padrão "traz as linhas erradas, assert que veio vazio"
A ponte com a Trilha 1
No módulo 6 da Trilha 1 você escreveu queries que procuram linha errada: pedido não-cancelado com valor 0, item com quantidade 0, e-mail duplicado. A query já era a validação. Agora é só embrulhar num teste:
def test_item_tem_quantidade_positiva(db):
ruins = db.execute(
"SELECT id, pedido_id, quantidade FROM itens_pedido WHERE quantidade <= 0"
).fetchall()
assert ruins == [], f"itens com quantidade <= 0: {[r['id'] for r in ruins]}"
A receita, sempre igual:
- a query
SELECTtraz só as linhas que violam a regra; assert ruins == []: passa quando não há nenhuma;- a mensagem do
assertlista quais linhas quebraram, pra você já sair caçando.
Nem toda validação é "igual a zero"
Às vezes o que você quer vigiar é uma proporção ou um
teto. Em test_03_regras_negocio.py:
proporcao = sem_defeito / total_falhas
assert proporcao <= 0.30, f"{proporcao:.0%} das falhas sem defeito ligado, acima de 30%"
O assert aceita qualquer expressão booleana. E o
texto depois da vírgula é a mensagem que aparece quando falha.
xfail: "eu já sei que este falha"
O banco de prática tem bugs plantados de propósito
(a Trilha 1 avisa isso). Então três testes de test_02_integridade.py
estão certos, mas o dado está torto, eles falhariam. Pra suíte não ficar vermelha
por causa disso, eles levam:
@pytest.mark.xfail(reason="bug plantado: 2 itens de pedido com quantidade 0", strict=True)
def test_item_tem_quantidade_positiva(db):
...
- XFAIL no relatório = "falhou, como esperado". Não derruba o build.
strict=True: se um dia ele passar (o dado foi corrigido), o pytest marca XPASS como erro, te lembrando de remover o marcador.- Diferente de
skip:skipnem roda;xfailroda e confere que ainda está quebrado.
Exercício: pegue o bug
- Em
test_02_integridade.py, apague a linha@pytest.mark.xfail(...)de cima detest_pedido_nao_cancelado_nao_tem_valor_zero. pytest -v test_02_integridade.py. Agora fica FAILED: leia a mensagem: ela lista os ids dos pedidos (17, 88, 143).- Confirme no banco com a Trilha 1 / SQLite:
SELECT * FROM pedidos WHERE id IN (17, 88, 143); - Recoloque o
@pytest.mark.xfail. Isso é o fluxo real: o teste vermelho é o bug report.
Num projeto de verdade você abriria o defeito, e o teste só voltaria a verde quando o dado (ou a regra) fosse corrigido.
Olhar de QA
Este é o módulo que fecha a ponte: a query de investigação que você escreveu uma vez vira uma linha de defesa que roda para sempre. E cuide da mensagem do assert com o mesmo rigor do título de um relatório de bug, porque no pipeline ninguém está olhando a tela quando o teste falha. Aquela mensagem é o relatório. Se ela não disser quais linhas quebraram, alguém vai ter que descobrir de novo.