CTest Debugging in VSCode

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.

🔗 Web: CMake
📧 📋 🐘 | 🔗 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!