Crucible — testes
No cadinho o metal é provado no fogo. DataForge molda, Kiln assa, Crucible prova.
Crucible é o framework de testes da linguagem. Tem sintaxe própria — dez palavras contextuais — e 59 matchers.
crucible "Calculadora":
setup:
base := 10
trial "soma dois números":
expect 2 + 2 is 4
trial "recusa divisão por zero":
expect(lambda => 1 / 0).to_raise(DivisionByZeroError)
trial "vê o setup":
expect base is 10$ dataforge crucible
✓ Calculadora 3 trial(s), 84µs
────────────────────────────────────────
3 passou em 100µsPor que um framework próprio#
O dataforge test que já existia roda arquivos *_test.df e conta assert. Isso responde "passou?" e nada mais. Quando falha, a mensagem diz que uma expressão deu falso — não o que se esperava, o que veio, nem qual dos quarenta casos daquele arquivo era.
O Crucible responde as outras perguntas:
$ dataforge crucible
✗ Carrinho 4 trial(s), 1.2ms
✗ soma o frete
────────────────────────────────────────
1) Carrinho > soma o frete
testes/carrinho.df:18
devia ser {"total": 130, "frete": 30}, e veio
{"total": 100, "frete": 30}
~ "total": esperava 130, veio 100Comparar dois vaults de dez chaves lendo os dois inteiros não se faz — o Crucible aponta a chave que difere.
As garantias#
- Um trial não vaza para o próximo. Cada um roda no próprio quadro de escopo, com as fixtures reconstruídas. Um teste que passa sozinho e falha na suíte seria bug do framework.
- A limpeza roda mesmo com falha.
teardowne a parte da fixture depois doproviderodam em qualquer saída. - A ordem não importa. Com
--aleatorioa suíte embaralha; um teste que depende de ordem falha ali, e não seis meses depois. - A diferença é mostrada, não descrita.
Isolamento, na prática#
crucible "Isolamento":
setup:
contador := 0
trial "o primeiro soma":
contador := contador + 1
expect contador is 1
trial "o segundo vê o valor original":
expect contador is 0Os dois passam. O setup roda antes de cada trial, num quadro novo — o que o primeiro escreveu não existe para o segundo.
As dez palavras#
| Palavra | O que abre |
|---|---|
crucible | uma suíte; suítes aninham |
trial | um caso de teste |
expect | uma cobrança |
setup | roda antes de cada trial (setup all uma vez) |
teardown | roda depois de cada trial |
fixture | preparo e limpeza no mesmo lugar |
provide | entrega o valor preparado, e divide a fixture |
tagged | marca, para filtrar depois |
pending | não roda, e o relatório diz por quê |
bench | mede em vez de cobrar |
Rodando#
dataforge crucible # tudo
dataforge crucible -v # mostra também o que passou
dataforge crucible --filtro=carrinho # só os que casam
dataforge crucible --tag=rapido # só os marcados
dataforge crucible --sem-tag=rede # pula os marcados
dataforge crucible --aleatorio # embaralha a ordem
dataforge crucible --semente=42 # repete um embaralhamento
dataforge crucible --repetir=10 # cada trial 10 vezes
dataforge crucible --prazo=500 # falha o que passar de 500ms
dataforge crucible --fail-fast # para na primeira falha
dataforge crucible --formato=junit --out=r.xml
dataforge crucible --matchers # lista os 59Por onde seguir#
Os 59 matchers
igualdade, tipos, coleções, erros, desempenho
Fixtures e ganchos
preparo, limpeza e por que elas ficam juntas
Dublês
mock, spy e stub — e a diferença entre eles
Teste por propriedade
a regra em vez dos casos, com contraexemplo encolhido
Relatórios e CI
texto, JUnit, JSON, TAP — e benchmark com p95