Pular para o conteúdo

Testes instáveis

O teste que passa e falha sem mudar nada — as cinco causas, e por que repetir não é a correção.

Um teste instável é pior que nenhum: ele ensina o time a rodar o CI de novo em vez de ler a falha. E no dia em que a falha é real, ela é tratada como ruído. Toda instabilidade tem uma causa, e a causa quase sempre é uma destas cinco.

CausaSintomaCorreção
tempofalha perto da meia-noite, ou numa máquina lentarelógio falso: Crucible.com_relogio / freeze_time
ordempassa sozinho, falha na suíteestado compartilhado — um banco novo por teste
aleatoriedadefalha uma vez em vintesemente fixa, ou teste por propriedade com a semente no relatório
concorrênciafalha só no CI, que tem outro número de núcleossincronizar de verdade; medir com Crucible.corrida
medida absoluta“devia levar menos de 50 ms”comparar uma razão contra a mesma máquina

Tempo: o relógio que você controla#

dataforge
adopt Arcane.Crucible

action vencido(prazo, agora):
    yield agora bigger prazo

crucible "prazo":
    trial "vence depois do prazo, e nao antes":
        expect vencido(1000, 999) is no
        expect vencido(1000, 1000) is no
        expect vencido(1000, 1001) is yes

r := Crucible.run()
assert r["falhou"] is 0

// A regra recebe 'agora' como argumento. Uma acao que chama time()
// por dentro so e testavel na hora certa do dia.

Repetir não é corrigir#

Crucible.flaky(acao, tentativas) existe, e devolve quantas tentativas foram precisas — um teste que precisa de três toda vez não é instável, está quebrado. Use-o como diagnóstico, nunca como correção permanente.

Continue em Cenários de concorrência e relógio.