Cómo hacer pruebas en el track de D

Aprende a probar tus ejercicios de D en Exercism


Cada ejercicio incluye los tests unitarios. Tú aportas la implementación. Cada archivo genera un ejecutable de consola que ejecuta los tests. Ejecutar el ejecutable de tests imprime mensajes por cada test que falla y reporta un estado de salida distinto de cero cuando los tests fallan.

Nota Tu código se prueba con el conjunto de tests cada vez que compilas tu proyecto. Si tu código no pasa uno o más tests pero es código D válido, igual se compila.

Trabajar en cada ejercicio es un proceso que consiste en:

  • Ejecutar los tests con dub test
    • Si decidiste no instalar DUB, en su lugar usarías dmd source/*.d -de -w -main -unittest y luego ejecutarías el binario resultante.
  • Para cada test unitario:
    • Resuelve los errores de compilación para que el test falle.
    • Implementa solo lo necesario para que el test pase.
    • Refactoriza tu implementación para mejorar la legibilidad, reducir la duplicación, etc.
    • Habilita el siguiente test

Nota: D tiene soporte para tests unitarios directamente en el lenguaje, así que los tests unitarios suelen estar en el mismo archivo que la implementación. Los tests unitarios se ejecutan antes del cuerpo de main y se habilitan en el ejecutable final usando la opción de compilador -unittest.

Cómo interpretar la salida de los tests unitarios

Si todos los tests pasan, la salida de los tests podría verse así

$ 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

La salida de los tests puede ser difícil de leer cuando hay tests que fallan.

$ 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

Hay una traza de pila muy detallada ahí, pero la línea importante es la que está justo arriba de ----------------

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

Esa línea te dice que la aserción que falla está en la línea 102 del archivo dnd_character.d. Puedes usar eso para identificar con precisión el test que no cumple con lo esperado.