Exercism에서 D 연습 문제를 테스트하는 방법을 알아봐요
각 연습 문제는 단위 테스트를 제공해요. 구현은 직접 작성해요. 각 파일은 테스트를 실행하는 콘솔 실행 파일을 만들어요. 테스트 실행 파일을 실행하면 실패한 테스트마다 메시지를 출력하고, 테스트가 실패하면 0이 아닌 종료 상태를 보고해요.
참고 프로젝트를 빌드할 때마다 코드가 테스트 스위트에 대해 테스트돼요. 코드가 하나 이상의 테스트를 통과하지 못하더라도 유효한 D 코드라면 여전히 컴파일돼요.
각 연습 문제를 풀어 나가는 과정은 다음과 같아요:
dub test로 테스트를 실행해요
dmd source/*.d -de -w -main -unittest를 사용한 다음, 만들어진 실행 파일을 실행해요.참고: D는 언어 자체에서 단위 테스트를 지원하기 때문에, 보통 단위 테스트는 구현과 같은 파일에 있어요. 단위 테스트는 main 본문보다 먼저 실행되며, 최종 실행 파일에서는 -unittest 컴파일러 스위치를 사용해 활성화돼요.
모든 테스트가 성공하면, 테스트 출력은 이렇게 보일 수 있어요
$ 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
테스트가 실패하면 출력을 읽기 어려울 수 있어요.
$ 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
여기에는 자세한 스택 트레이스가 잔뜩 있지만, 중요한 줄은 ---------------- 바로 위에 있는 줄이에요.
core.exception.AssertError@source/dnd_character.d(102): unittest failure
그 줄은 실패한 단언이 dnd_character.d 파일의 102번째 줄에 있다는 것을 알려줘요. 이를 이용해 기대에 맞지 않는 테스트를 정확히 짚어낼 수 있어요.