← Mundo bit ByteQualidade e Teste de Software
Professor Ronaldo Lavestein
Repetir com o computador
Etapa 11

Automatizando repetições

Na etapa anterior, vimos que a regressão pode exigir os mesmos testes muitas vezes. Agora a pergunta é prática: quando o trabalho é repetitivo e previsível, por que não deixar o computador executar parte dele?

A mesma sequência outra vez

Depois de cada alteração na Cantina Horizonte, alguém testa manualmente as quantidades 0, 1, 5, 10 e 11.

No começo são cinco verificações rápidas. Depois chegam cupom, estoque, total e status. O conjunto cresce.

O problema não é que o teste manual deixou de ser útil. O problema é gastar tempo humano repetindo comparações que seguem sempre a mesma regra.

Automatizar não muda o raciocínio do teste

Veja um caso que já conhecemos:

Entrada: quantidade 5.

Esperado: valor aceito.

Obtido: resultado da função.

Comparação: esperado e obtido são iguais?

Num teste automatizado, o computador executa a entrada e faz essa comparação por nós.

Conhecendo o pytest

A Cantina Horizonte usa Python. Para automatizar testes nessa linguagem, vamos usar pytest, uma ferramenta que encontra e executa testes escritos em Python.

O projeto já possui um arquivo chamado test_smoke.py. A palavra inglesa smoke aparece em smoke test, expressão usada para uma verificação rápida de que o sistema básico continua funcionando.

def test_fluxo_normal_quantidade_valida():
    assert validar_quantidade(2) is True

A palavra assert é um comando do Python usado aqui para declarar aquilo que esperamos que seja verdadeiro. Se a condição for verdadeira, o teste passa. Se não for, o teste falha.

Antes do primeiro teste automatizado

Até aqui foi possível experimentar boa parte do módulo apenas pelo navegador. Agora vamos executar código Python no seu computador.

No Windows, use o caminho mais simples

  1. Na pasta qts/cantina-horizonte-v1, dê dois cliques em iniciar_windows.bat uma vez. Na primeira execução, ele cria o ambiente do projeto e instala as dependências.
  2. Quando a Cantina abrir normalmente, volte à janela do servidor e pressione Ctrl+C para encerrá-lo.
  3. Abra o terminal nessa mesma pasta.

A pasta .venv guarda um ambiente virtual do Python: uma instalação isolada para as dependências deste projeto, sem misturá-las com outros projetos do computador.

Se você já ativou esse ambiente virtual, pode usar python nos comandos a seguir. Se não ativou, no Windows use diretamente .venv\Scripts\python.exe.

Execute os primeiros testes

Com o ambiente virtual ativado:

python -m pytest

Ou, no Windows, sem ativá-lo:

.venv\Scripts\python.exe -m pytest

O comando pede ao Python que execute o módulo pytest. Ele procura arquivos e funções de teste seguindo convenções de nomes, como arquivos iniciados por test_.

No projeto inicial, as verificações básicas devem passar porque elas cobrem apenas um fluxo normal já conhecido.

Agora escreva um teste que represente a regra completa

Crie, na pasta tests, um arquivo chamado test_quantidade.py e comece com:

from backend.app import validar_quantidade


def test_quantidade_zero_deve_ser_rejeitada():
    assert validar_quantidade(0) is False

Leia o nome da função como uma frase: quantidade zero deve ser rejeitada. Um bom nome ajuda a entender qual comportamento está protegido.

Um teste vermelho pode ser uma boa notícia

Execute novamente o pytest. Na versão inicial da Cantina Horizonte, esse novo teste deve falhar.

O teste falhou porque está errado ou porque acabou de revelar o defeito que já conhecíamos?

Neste caso, o teste está expressando corretamente o requisito. A falha é uma evidência de que o comportamento atual não atende à regra.

Corrija a regra na sua cópia do projeto

A validação correta precisa considerar os dois limites:

def validar_quantidade(quantidade: int) -> bool:
    return 1 <= quantidade <= 10

Execute novamente os testes. Agora o caso de quantidade zero deve passar.

Transforme a regressão em código

Não pare no caso que acabou de ser corrigido. Acrescente outros pontos importantes:

def test_quantidade_um_deve_ser_aceita():
    assert validar_quantidade(1) is True


def test_quantidade_cinco_deve_ser_aceita():
    assert validar_quantidade(5) is True


def test_quantidade_dez_deve_ser_aceita():
    assert validar_quantidade(10) is True


def test_quantidade_onze_deve_ser_rejeitada():
    assert validar_quantidade(11) is False

Perceba como técnicas aprendidas antes continuam presentes: 0, 1, 10 e 11 vieram da análise dos limites; 5 representa uma faixa válida.

Automação não substituiu a técnica de teste. Ela automatizou a execução de casos escolhidos com técnica.

Vamos provocar uma regressão de propósito

Altere temporariamente a função para:

return 1 <= quantidade < 10

Execute os testes novamente. O caso de quantidade 10 deve falhar.

Depois restaure:

return 1 <= quantidade <= 10

Essa pequena experiência mostra por que uma suíte de regressão automatizada pode detectar rapidamente um comportamento quebrado por uma alteração.

Suíte de testes

Suíte de testes

É um conjunto de testes organizado para ser executado em conjunto. A palavra suíte aqui significa coleção ou conjunto relacionado.

Com o tempo, a Cantina Horizonte pode ter testes de quantidade, subtotal, cupom, estoque e outras regras. Executar o pytest pode rodar todos eles de uma vez.

Nem tudo deve ser automatizado só porque pode

Automação costuma ser especialmente útil em testes repetitivos, estáveis e importantes para regressão.

Exploração, percepção visual, experiência de uso e situações novas ainda podem exigir bastante observação humana.

SituaçãoPor que automatizar ou manter observação humana?
Validar 0, 1, 10 e 11 em toda versãoRepetitivo e com resultado objetivo: bom candidato à automação.
Explorar uma tela recém-criadaA investigação humana pode descobrir situações ainda não previstas.
Calcular desconto do MBB10 em dezenas de execuçõesRegra estável e comparação objetiva: automação ajuda muito.
Avaliar se uma mensagem é compreensívelHá julgamento de uso e contexto que não se resume a uma comparação numérica.

Os testes passaram. Quanto do código eles realmente percorreram?

Essa pergunta nos leva à cobertura de código.

Cobertura de código

É uma medida que mostra quanto do código foi executado durante os testes. Uma forma comum é observar a porcentagem de linhas executadas.

No projeto, instalamos o complemento pytest-cov. Ele adiciona informações de cobertura ao pytest.

O nome backend no comando abaixo indica a pasta que contém o código Python executado no lado do servidor da Cantina Horizonte.

python -m pytest --cov=backend --cov-report=term-missing

Se estiver usando o Python do ambiente virtual sem ativá-lo, substitua python por .venv\Scripts\python.exe.

O relatório mostra a porcentagem de linhas executadas e, com term-missing, também indica linhas que não foram percorridas pelos testes.

100% de cobertura não significa 100% de qualidade

Imagine esta função:

def validar_quantidade(qtd):
    return qtd <= 10

Um único teste com quantidade 5 pode executar a única linha da função e produzir cobertura de 100% dessa função.

Mesmo assim, quantidade 0 e valores negativos continuam errados.

Cobertura responde “que código foi executado?”, não “todos os comportamentos importantes foram verificados?”.

Três ideias que precisam permanecer juntas

Técnica escolhe bons casos→Automação repete→Cobertura mostra o que foi percorrido

Nenhuma dessas três coisas, sozinha, prova que o software está perfeito.

E em outras linguagens?

A ideia não pertence ao Python. Em Java, por exemplo, é comum encontrar JUnit para testes e JaCoCo para cobertura. Em projetos JavaScript, ferramentas como Vitest podem cumprir papel semelhante.

Neste módulo seguimos uma única trilha prática com Python e pytest para não transformar QTS em três cursos paralelos.

Prática · construa uma pequena suíte

  1. Execute os testes existentes.
  2. Crie os cinco testes de quantidade: 0, 1, 5, 10 e 11.
  3. Veja o teste de 0 falhar na versão inicial.
  4. Corrija a validação na sua cópia e execute novamente.
  5. Provoque a regressão trocando <= 10 por < 10 e observe qual teste acusa o problema.
  6. Restaure a regra correta e gere o relatório de cobertura.

Agora podemos inverter a ordem

Até aqui o caminho foi:

Regra existente→Código→Teste

Mas imagine que a cantina peça uma nova regra que ainda não existe:

Pedidos com subtotal a partir de R$ 100,00 terão entrega gratuita.

Se já sabemos exatamente o comportamento esperado, será que podemos escrever o teste antes de implementar a regra?

A seguir: escrever o teste antes do código

Vamos conhecer o Desenvolvimento Guiado por Testes, em inglês Test-Driven Development — TDD — fazendo uma nova funcionalidade nascer do ciclo teste → código → melhoria.

Antes de seguir

Você deve conseguir explicar:

  • o que o pytest automatiza;
  • o que significa assert em um teste;
  • por que um teste que falha pode estar funcionando corretamente;
  • o que é uma suíte de testes;
  • o que cobertura de código informa e, principalmente, o que ela não garante.