← Curso IA na prática para Programadores: do prompt ao pull request 22 aulas
Escrever código em ciclos curtos

Testes que passam e não provam nada

Armadilha 9 min de leitura

Cinco padrões de teste inútil que a IA gera com frequência, com o código de cada um e o que colocar no lugar.

Peça "testes para essa função" e você recebe testes. Eles passam. A cobertura sobe. E o bug continua passando junto.

Ao final desta aula você consegue
  • Identificar os cinco padrões de teste que não detectam regressão.
  • Entender por que a IA os produz com tanta frequência.
  • Pedir testes de um jeito que reduza esses padrões.

Há um motivo estrutural para isso: um teste que passa é a saída mais provável quando o pedido foi "escreva testes". Nada no pedido exigiu poder de detecção. E teste que passa parece sucesso — para o modelo e para quem lê rápido.

1. A asserção que não afirma nada

Passa com quase qualquer implementação
test('calcula o frete', () => {
  const r = calcularFrete(pedido);
  expect(r).toBeDefined();
  expect(typeof r).toBe('number');
});

Retornar 0 sempre passa. Retornar o valor errado passa. Só falha se a função explodir.

Afirma a regra
test('frete é grátis acima de R$ 200 no subtotal', () => {
  expect(calcularFrete({ subtotal: 200.00, uf: 'PR' })).toBe(0);
  expect(calcularFrete({ subtotal: 199.99, uf: 'PR' })).toBe(24.90);
});

Fixa o limite exato e o comportamento nos dois lados dele. Mudar o corte para 250 quebra o teste — que é o objetivo.

A diferença: A segunda versão testa a fronteira. 200,00 e 199,99 valem mais que dez casos no meio da faixa.

2. O mock que cobre justamente o que se quer testar

O teste do próprio mockpython
def test_aplica_desconto(mocker):
    mocker.patch('pedido.calcular_desconto', return_value=10.0)

    total = finalizar_pedido(pedido)

    assert total == 90.0   # 100 - 10
A função de desconto — a regra que interessa — foi substituída por um valor fixo. O teste prova que 100 menos 10 dá 90.

Mock existe para isolar o que é caro ou instável: rede, relógio, sistema de arquivos, serviço externo. Quando o mock cobre a regra de negócio, o teste vira decoração.

3. O teste espelho da implementação

Repete a conta em vez de fixar o esperadophp
public function test_calcula_total(): void
{
    $itens = [['preco' => 10.0, 'qtd' => 3]];

    $esperado = $itens[0]['preco'] * $itens[0]['qtd'];   // ← a mesma conta
    $this->assertSame($esperado, $this->carrinho->total($itens));
}
Se a regra estiver errada nos dois lugares — e vai estar, porque saíram da mesma cabeça — o teste passa alegremente. O valor esperado precisa ser uma constante: 30.0.

4. O teste que depende do relógio ou da ordem

Verde hoje, vermelho no dia 31
$vencimento = date('Y-m-d', strtotime('+30 days'));
$this->assertSame($vencimento, $fatura->vencimento());

Passa quase sempre e falha na virada de mês, no ano bissexto e no horário de verão — sempre quando ninguém tem tempo.

Relógio controlado
$this->travarRelogioEm('2026-01-31 10:00:00');

$fatura = $this->gerarFatura();

$this->assertSame('2026-03-02', $fatura->vencimento());

Determinístico e, de quebra, documenta a decisão sobre o que acontece quando 31 + 30 dias cai em mês curto.

A diferença: Teste que depende de relógio, ordem de execução, rede ou estado deixado por outro teste não é teste — é sorteio. E o time aprende a reexecutar em vez de investigar.

5. Cobertura alta sem asserção relevante

É possível chegar a 90% de cobertura executando todas as linhas sem afirmar nada sobre elas. Cobertura mede o que foi executado, não o que foi verificado. Um relatório de cobertura alto com os quatro padrões acima é pior que nenhum relatório, porque cria confiança injustificada.

Pedido de teste que reduz os cinco padrões
Escreva testes para a regra abaixo.

Regra: [Dado/Quando/Então com números]
Código: [cole]
Stack de teste: [framework e versão]

Regras obrigatórias:
- Cada teste afirma um valor concreto e esperado, escrito como constante.
  Proibido recalcular o esperado a partir da entrada.
- Proibido assertion genérica (toBeDefined, notNull, typeof).
- Cubra as fronteiras da regra, não só o caso do meio.
- Mock só para relógio, rede e sistema de arquivos. Nunca para a regra.
- Nenhum teste pode depender de data atual, ordem de execução ou
  estado deixado por outro teste.

Depois dos testes, responda: para cada teste, qual alteração no código
faria ele ficar vermelho? Se você não souber responder para algum,
esse teste é fraco — reescreva.

A pergunta final é o filtro mais eficiente da lista. Um teste sem resposta clara para "o que faria ele quebrar?" é um teste sem poder de detecção.

PadrãoComo detectar no seu repositório
Asserção genéricaBuscar por toBeDefined, assertNotNull, isinstance
Mock da regraBuscar por mock cujo alvo esteja no mesmo módulo do teste
Espelho da implementaçãoBuscar por operador aritmético dentro do arquivo de teste
Dependência de relógioBuscar por now, today, strtotime, Date() em testes
Cobertura vaziaSabotar o código e ver quantos testes ficam vermelhos

A última linha é a única medida honesta de qualidade de suíte — as outras quatro são atalhos rápidos.

Checagem antes de seguir
  • Todo valor esperado é constante escrita à mão.
  • Nenhuma asserção genérica sobrou.
  • Nenhum mock cobre a regra sob teste.
  • Nenhum teste lê o relógio real.
  • A suíte fica vermelha quando o código é sabotado.
Em uma frase
  • A pergunta que separa teste de decoração: qual mudança no código faria este teste ficar vermelho?

Comentários e dúvidas

Inscreva-se grátis para comentar, tirar dúvidas, marcar seu progresso e emitir o certificado ao fim do curso.

Inscrever-se grátis com Google

Ainda não há comentários nesta aula.