Pular para o conteúdo

Cobertura de testes

Quais linhas os testes executaram, e por que os dois lados da fração precisam estar certos.

Uma suíte verde não diz nada sobre o que ela não exercita. 13 passaram não distingue "o sistema está testado" de "os treze caminhos fáceis estão testados" — e num sistema de 200 arquivos, o código que ninguém tocou é exatamente onde o bug mora.

Como se pede#

bash
dataforge test --cobertura
dataforge test --cobertura --linhas     # as linhas descobertas, em faixas
dataforge test --minimo=80              # reprova abaixo disso (saída 1)

dataforge crucible --cobertura          # o mesmo, no Crucible
text
  src/main.df         ░░░░░░░░░░░░░░░░░░░░   0.0%  0/94
                      sem teste: montar_cli, mostrar, principal
  src/repositorio.df  ████████████████████ 100.0%  38/38
  src/tarefa.df       ████████████████████ 100.0%  14/14

  total  35.6%  52 de 146 linhas executáveis

--minimo aceita 80, 80% e 0.8. A fronteira é em 1 inclusive: --minimo=1 é um por cento, porque ninguém exige cobertura total digitando 1.

A informação que resolve#

58% coberto não diz o que fazer. `sem teste: nunca_chamada` diz.

Por isso o relatório lista, para cada arquivo, os nomes das ações cujo corpo nunca rodou — e com --linhas, as linhas em faixas (3-5, 9, 11-12), porque uma lista de setenta números é ilegível.

Os dois lados da fração#

Cada metade tem um jeito próprio de mentir, e as duas foram tratadas:

MetadeDe onde vemComo mentiria
denominadoro parser: quais linhas são executáveiscontar comentário e linha vazia dá um número sempre pessimista, que ninguém olha duas vezes
numeradora execução, instrumentadacom a compilação de corpos ligada, o corpo das ações passa por fora e toda ação daria 0%

E duas escolhas que mudam o que se lê:

O que ela não mede#

É de linha, e não de ramo: given a and b conta como coberta mesmo que b nunca tenha sido avaliado. Medir ramo exigiria instrumentar a avaliação de expressão, o que dobraria o custo — e cobertura de linha já responde a pergunta que importa, que é "existe código que ninguém testou".

No CI#

yaml
- name: testes com cobertura mínima
  run: dataforge test --minimo=80

O comando devolve 1 quando fica abaixo, então o job falha. Comece pelo número que você já tem, e suba-o um ponto por vez — um mínimo de 80% num projeto a 35% só ensina a desligar a verificação.

Uma advertência#

Cobertura alta não é qualidade. Um teste que chama tudo e não verifica nada dá 100%:

dataforge
action test_nao_verifica_nada():
    processar_pedido(pedido)      // coberto a 100%, zero garantido

O número serve para achar o que está a zero, e é aí que ele vale quase tudo o que custa. Para o resto, `Crucible` — matchers, dublês, teste por propriedade e instantâneo.

`forge_modules/` fica de fora#

Os testes das suas dependências não são os seus. Um projeto com 13 testes relatava 89, e a suíte ficava vermelha por falha de uma biblioteca que ninguém escreveu.