Pular para o conteúdo

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.

dataforge
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
bash
$ dataforge crucible

   Calculadora  3 trial(s), 84µs

  ────────────────────────────────────────
  3 passou   em 100µs

Por 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:

bash
$ 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 100

Comparar 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. teardown e a parte da fixture depois do provide rodam em qualquer saída.
  • A ordem não importa. Com --aleatorio a 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#

dataforge
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 0

Os 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#

PalavraO que abre
crucibleuma suíte; suítes aninham
trialum caso de teste
expectuma cobrança
setuproda antes de cada trial (setup all uma vez)
teardownroda depois de cada trial
fixturepreparo e limpeza no mesmo lugar
provideentrega o valor preparado, e divide a fixture
taggedmarca, para filtrar depois
pendingnão roda, e o relatório diz por quê
benchmede em vez de cobrar

Rodando#

bash
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 59

Por onde seguir#