CTest Debugging in VSCode
« | 08 Dec 2024 | »Per CTest registrierte Tests aus CMake
können in VSCode auf viele
unterschiedliche Arten und Weisen gestartet werden.
Und jede hat ihre individuellen Eigenarten.
Ignorieren wir mal die “Problemchen”, die uns
CONAN einbrocken kann und sprechen
wir nur über CMake.
Natürlich kann man ein Test-Programm-Target auch als normales CMake-Debug Target
auswählen und ganz normal zum Debugging starten … doch darum soll es hier nicht
gehen.
Wird ein Target als Test per add_test() registriert, erscheint der Test auch
in VSCode’s Test Explorer.
Dort kann der Test per Klick gestartet werden, was CMake anwirft und dieses
dann den Test regulär startet.
Neben dem Start-Pfeil-Button, gibt es noch den Start-Debugging Button neben
jedem Test.
Beim einem Klick darauf braucht VSCode wieder eine Launch-Konfiguration, die
in etwa so aussehen kann:
1// .vscode/launch.json 2{ 3 "version": "0.2.0", 4 "configurations": [ 5 { 6 "name": "(gdb) CTest Launch", 7 "type": "cppdbg", 8 "MIMode": "gdb", 9 "request": "launch", 10 "program": "${cmake.testProgram}", 11 "args": [ "${cmake.testArgs}" ], 12 "cwd": "${cmake.testWorkingDirectory}" 13 }, 14 { 15 "name": "(msvc) CTest Launch", 16 "type": "cppvsdbg", 17 "request": "launch", 18 "program": "${cmake.testProgram}", 19 "args": [ "${cmake.testArgs}" ], 20 "cwd": "${cmake.testWorkingDirectory}" 21 } 22 ] 23}
Beim “Start-Debugging” erscheint ein Menüs, das uns die beiden definierten
Möglichkeiten anbietet und startet einen Debug-Prozess basierend auf den
CTest-Einstellungen, die wir gewählt haben.
Und wenn diese Einstellungen falsch sind, startet gar nichts.
CMake Generator Unterschiede
Ein gravierenden Unterschied zwischen MSVC und den anderen Compilern ist die
Visual Studio Solution, und ihre Projekte, die Debug und Release-
Konfigurationen beinhalten, während für andere Compiler eine Konfiguration
vorausgewählt werden muss.
Das führt dazu, dass ein GCC immer genau ein Ausgabeverzeichnis für Programme
und Bibliotheken hat, doch Visual Studio erhält zwei, einmal Debug und einmal
Release.
Der add_test() Test muss also wissen, wie er Debug und Release-Konfigurationen
unterschiedlich verwaltet.
Jetzt kommt noch ein weiterer Fall hinzu: nämlich
Ninja.
Ninja-Build kann das Bauen wie MSBuild verwalten, verzichtet aber auf
Solutions oder VS-Projekte und setzt das unkompliziertere GCC Schema mit
genau einem vorkonfigurierten Build-Type ein.
Aus diesem Grund sieht meine add_my_test() Funktion so aus:
1set(APP_EXECUTABLE ${PROJECT_NAME}) 2set(TEST_ARGS) 3get_target_property(OUTPUT_FOLDER ${TARGET_NAME} RUNTIME_OUTPUT_DIRECTORY) 4if(MSVC AND NOT (${CMAKE_GENERATOR} MATCHES "Ninja")) 5 set(TEST_WORKING_DIRECTORY "${OUTPUT_FOLDER}/$<CONFIG>") 6else() 7 set(TEST_WORKING_DIRECTORY "${OUTPUT_FOLDER}") 8endif() 9add_test(NAME "${TEST_NAME}" WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}" COMMAND "${APP_EXECUTABLE}" ${TEST_ARGS})
Fazit
Mit der Launch-Konfiguration für CTest und ein paar Anpassungen für den Start
kann jedes Testprogramm auch aus dem VSCode Testing-Tab zum Debuggen gestartet
werden.
Ich wünschte, ich hätte CTest und VSCode schon 10 Jahre früher kennen gelernt
und eingesetzt, denn strukturiertes Testen kann die Qualität der
Softwareentwicklung nachhaltig verbessern.