Testar no percurso de D

Aprende a testar os teus exercícios de D no Exercism


Cada exercício fornece os testes unitários. Tu escreves a implementação. Cada ficheiro produz um executável de consola que corre os testes. Ao correr o executável de testes, é impressa uma mensagem por cada teste que falha e é reportado um estado de saída diferente de zero quando os testes falham.

Nota O teu código é testado com o conjunto de testes sempre que compilas o teu projeto. Se o teu código não passar num ou mais testes, mas for código D válido, ainda assim é compilado.

Percorrer cada exercício é um processo de:

  • Correr os testes com dub test
    • Se optaste por não instalar o DUB, usa antes dmd source/*.d -de -w -main -unittest e depois corre o binário resultante.
  • Para cada teste unitário:
    • Corrige os erros de compilação para que o teste falhe.
    • Implementa apenas o suficiente para o teste passar.
    • Refatora a tua implementação para melhorar a legibilidade, reduzir duplicação, etc.
    • Ativa o teste seguinte

Nota: O D tem suporte para testes unitários diretamente na linguagem, por isso, normalmente, os testes unitários ficam no mesmo ficheiro que a implementação. Os testes unitários são executados antes do corpo de main e são ativados no executável final através da opção do compilador -unittest.

Interpretar a saída dos testes unitários

Se todos os testes passarem, a saída dos testes pode ter este aspeto

$ dub test
             Generating test runner configuration 'dnd-character-test-library' for 'library' (library).
    Starting Performing "unittest" build using dmd for x86_64.
    Building dnd-character ~master: building configuration [dnd-character-test-library]
     Linking dnd-character-test-library
     Running dnd-character-test-library
1 modules passed unittests

A saída dos testes pode ser difícil de ler quando há testes que falham.

$ dub test
             Generating test runner configuration 'dnd-character-test-library' for 'library' (library).
    Starting Performing "unittest" build using dmd for x86_64.
    Building dnd-character ~master: building configuration [dnd-character-test-library]
     Linking dnd-character-test-library
     Running dnd-character-test-library
core.exception.AssertError@source/dnd_character.d(102): unittest failure
----------------
??:? _d_unittestp [0x5568ff91bf05]
source/dnd_character.d:102 void dnd_character.__unittest_L30_C1() [0x5568ff911fee]
??:? void dnd_character.__modtest() [0x5568ff913760]
??:? int core.runtime.runModuleUnitTests().__foreachbody6(object.ModuleInfo*) [0x5568ff928f82]
??:? int object.ModuleInfo.opApply(scope int delegate(object.ModuleInfo*)).__lambda2(immutable(object.ModuleInfo*)) [0x5568ff9148f7]
??:? int rt.minfo.moduleinfos_apply(scope int delegate(immutable(object.ModuleInfo*))).__foreachbody2(ref rt.sections_elf_shared.DSO) [0x5568ff92003f]
??:? int rt.sections_elf_shared.DSO.opApply(scope int delegate(ref rt.sections_elf_shared.DSO)) [0x5568ff9200d1]
??:? int rt.minfo.moduleinfos_apply(scope int delegate(immutable(object.ModuleInfo*))) [0x5568ff91ffcd]
??:? int object.ModuleInfo.opApply(scope int delegate(object.ModuleInfo*)) [0x5568ff9148c9]
??:? runModuleUnitTests [0x5568ff928db7]
??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int function(char[][])*).runAll() [0x5568ff91d248]
??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x5568ff91d1d5]
??:? _d_run_main2 [0x5568ff91d13e]
??:? _d_run_main [0x5568ff91cf27]
/usr/include/dmd/druntime/import/core/internal/entrypoint.d:29 main [0x5568ff90f8f1]
??:? [0x7f473154a249]
??:? __libc_start_main [0x7f473154a304]
??:? _start [0x5568ff90f7e0]
1/1 modules FAILED unittests
Error Program exited with code 1

Há ali um stack trace detalhado, mas a linha importante é a que está acima de ----------------

core.exception.AssertError@source/dnd_character.d(102): unittest failure

Essa linha diz-te que a asserção que falha está na linha 102 do ficheiro dnd_character.d. Podes usar isso para identificar com precisão o teste que não corresponde ao esperado.