QA Learning / pytest

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:

  1. a query SELECT traz só as linhas que violam a regra;
  2. assert ruins == []: passa quando não há nenhuma;
  3. a mensagem do assert lista 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: skip nem roda; xfail roda e confere que ainda está quebrado.

Exercício: pegue o bug

  1. Em test_02_integridade.py, apague a linha @pytest.mark.xfail(...) de cima de test_pedido_nao_cancelado_nao_tem_valor_zero.
  2. pytest -v test_02_integridade.py. Agora fica FAILED: leia a mensagem: ela lista os ids dos pedidos (17, 88, 143).
  3. Confirme no banco com a Trilha 1 / SQLite: SELECT * FROM pedidos WHERE id IN (17, 88, 143);
  4. 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.

Terminou este módulo? Marque: o ✓ aparece no índice da trilha e a barra de progresso anda no começo do site. Fica salvo só no seu navegador.