Vor kurzem wurde mir die Verwendung von CMake zum Kompilieren meiner C ++ - Projekte verkauft, und ich möchte jetzt einige Komponententests für meinen Code schreiben. Ich habe mich entschieden, das Google Test-Dienstprogramm zu verwenden, um dies zu unterstützen, benötige jedoch Hilfe beim Einstieg.
Den ganzen Tag habe ich verschiedene Anleitungen und Beispiele gelesen, darunter den Primer , eine Einführung bei IBM und einige Fragen zu SO ( hier und hier ) sowie andere Quellen, die ich aus den Augen verloren habe. Mir ist klar, dass es da draußen viel gibt, aber irgendwie habe ich immer noch Schwierigkeiten.
Ich versuche derzeit, den grundlegendsten Test zu implementieren, um zu bestätigen, dass ich gtest richtig kompiliert / installiert habe und es nicht funktioniert. Die einzige Quelldatei (testgtest.cpp) stammt fast genau aus dieser vorherigen Antwort:
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
und meine zugehörige CMakeLists.txt lautet wie folgt:
cmake_minimum_required(VERSION 2.6)
project(basic_test)
# Setup testing
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})
# Add test cpp file
add_executable(runUnitTests
testgtest.cpp
)
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG})
add_test(
NAME runUnitTests
COMMAND runUnitTests
)
Beachten Sie, dass ich mich dafür entschieden habe, eine Verknüpfung mit gtest_main herzustellen, anstatt die Hauptdatei am Ende der CPP-Datei anzugeben, da ich glaube, dass ich dadurch das Testen einfacher auf mehrere Dateien skalieren kann.
Beim Erstellen der generierten SLN-Datei (in Visual C ++ 2010 Express) wird leider eine lange Liste von Fehlern des Formulars angezeigt
2>msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: virtual __thiscall std::basic_iostream<char,struct std::char_traits<char> >::~basic_iostream<char,struct std::char_traits<char> >(void)" (??1?$basic_iostream@DU?$char_traits@D@std@@@std@@UAE@XZ) already defined in gtestd.lib(gtest-all.obj)
was meiner Meinung nach bedeutet, dass ich nicht erfolgreich auf die gtest-Bibliotheken verlinke. Ich habe sichergestellt, dass ich beim Verknüpfen mit den Debug-Bibliotheken versucht habe, im Debug-Modus zu erstellen.
BEARBEITEN
Nachdem ich noch ein bisschen gegraben habe, denke ich, dass mein Problem etwas mit der Art der Bibliothek zu tun hat, in die ich gtest einbaue. Wenn beim Erstellen von gtest mit CMake das BUILD_SHARED_LIBS
Kontrollkästchen deaktiviert ist und ich mein Programm mit diesen .lib-Dateien verknüpfe, werden die oben genannten Fehler angezeigt . Wenn dies BUILD_SHARED_LIBS
jedoch aktiviert ist, erstelle ich eine Reihe von .lib- und .dll-Dateien. Beim Verknüpfen mit diesen .lib-Dateien wird das Programm kompiliert, beim Ausführen wird jedoch beanstandet, dass es gtest.dll nicht finden kann.
Was sind die Unterschiede zwischen einer SHARED
und einer Nicht- SHARED
Bibliothek, und wenn ich nicht freigegeben wähle, warum funktioniert es nicht? Gibt es in der CMakeLists.txt eine Option für mein Projekt, die mir fehlt?
quelle
ExternalProject_Add
anstatt verwendenadd_subdirectory
. Siehe diese Antwort für Details.enable_testing()
dasAntworten:
Die Lösung bestand darin, das Quellverzeichnis gtest als Unterverzeichnis Ihres Projekts zu speichern. Ich habe die funktionierende CMakeLists.txt unten eingefügt, wenn sie für jemanden hilfreich ist.
quelle
pthread
die verknüpften Bibliotheken ergänzen und die vorletzte Zeile intarget_link_libraries(runUnitTests gtest gtest_main pthread)
make test
, um die Tests auszuführen, oderctest
vom Build-Verzeichnis aus ausführen . Führen Sie ausctest -V
, um die Google-Testausgabe sowie diectest
Ausgabe anzuzeigen.Hier ist ein vollständiges Arbeitsbeispiel, das ich gerade getestet habe. Es wird direkt aus dem Internet heruntergeladen, entweder ein fester Tarball oder das neueste Subversion-Verzeichnis.
quelle
https://github.com/google/googletest/archive/release-1.8.0.zip
GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1
anstelle von URLhttps://github.com/google/googletest/archive/release-1.10.0.zip
Sie können das Beste aus beiden Welten bekommen. Es ist möglich,
ExternalProject
die gtest-Quelle herunterzuladen und dannadd_subdirectory()
zu Ihrem Build hinzuzufügen. Dies hat folgende Vorteile:Bei normaler Verwendung führt ExternalProject das Herunterladen und Entpacken nicht zum Zeitpunkt der Konfiguration durch (dh wenn CMake ausgeführt wird), aber Sie können dies mit ein wenig Arbeit erreichen. Ich habe einen Blog-Beitrag darüber geschrieben, der auch eine allgemeine Implementierung enthält, die für jedes externe Projekt funktioniert, das CMake als Build-System verwendet, nicht nur für gtest. Sie finden sie hier:
Update: Dieser Ansatz ist jetzt auch Teil der Googletest-Dokumentation .
quelle
Der Unterschied in den Compileroptionen zwischen Ihrer Testbinärdatei und der Google Testbibliothek ist höchstwahrscheinlich auf solche Fehler zurückzuführen. Aus diesem Grund wird empfohlen, Google Test im Quellformular einzubringen und zusammen mit Ihren Tests zu erstellen. In CMake ist das sehr einfach. Sie rufen einfach
ADD_SUBDIRECTORY
mit dem Pfad zum gtest-Stamm auf und können dann die dort definierten Ziele (gtest
undgtest_main
) der öffentlichen Bibliothek verwenden . In diesem CMake-Thread in der Gruppe googletestframework finden Sie weitere Hintergrundinformationen .[Bearbeiten] Die
BUILD_SHARED_LIBS
Option ist derzeit nur unter Windows wirksam. Es gibt den Typ der Bibliotheken an, die CMake erstellen soll. Wenn Sie dies festlegenON
, erstellt CMake sie als DLLs im Gegensatz zu statischen Bibliotheken. In diesem Fall müssen Sie Ihre Tests mit -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 erstellen und die vom CMake erstellten DLL-Dateien mit Ihrer Testbinärdatei in das Verzeichnis kopieren (CMake legt sie standardmäßig in einem separaten Ausgabeverzeichnis ab). Wenn gtest in der statischen Bibliothek nicht für Sie funktioniert, ist es einfacher, diese Option nicht festzulegen.quelle
Dies liegt daran, dass Sie -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 zu Compilerdefinitionen in Ihrem Projekt hinzufügen müssen, wenn Sie gtest als gemeinsam genutzte Bibliothek verwenden möchten.
Sie können auch die statischen Bibliotheken verwenden, vorausgesetzt, Sie haben sie mit der Option gtest_force_shared_crt kompiliert, um aufgetretene Fehler zu beseitigen.
Ich mag die Bibliothek, aber das Hinzufügen zum Projekt ist ein echtes Problem. Und Sie haben keine Chance, es richtig zu machen, es sei denn, Sie graben (und hacken) in die gtest-cmake-Dateien. Schande. Insbesondere gefällt mir die Idee, gtest als Quelle hinzuzufügen, nicht. :) :)
quelle
Das OP verwendet Windows, und eine viel einfachere Möglichkeit, GTest heute zu verwenden, ist vcpkg + cmake.
Installieren Sie vcpkg gemäß https://github.com/microsoft/vcpkg und stellen Sie sicher, dass Sie über
vcpkg
die cmd-Zeile ausgeführt werden können. Beachten Sie den vcpkg-Installationsordner, z.C:\bin\programs\vcpkg
.Installieren Sie gtest mit
vcpkg install gtest
: Hiermit wird GTest heruntergeladen, kompiliert und installiert.Verwenden Sie eine CmakeLists.txt wie folgt: Beachten Sie, dass wir Ziele verwenden können, anstatt Ordner einzuschließen .
Führen Sie cmake aus mit: (Bearbeiten Sie ggf. den Ordner vcpkg und stellen Sie sicher, dass der Pfad zur Toolchain-Datei vcpkg.cmake korrekt ist.)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:\bin\programs\vcpkg\scripts\buildsystems\vcpkg.cmake
und bauen
cmake --build build
wie gewohnt. Beachten Sie, dass vcpkg auch die erforderliche gtest (d) .dll / gtest (d) _main.dll aus dem Installationsordner in die Debug / Release-Ordner kopiert.Test mit
cd build & ctest
.quelle
Ihre und VladLosevs Lösungen sind wahrscheinlich besser als meine. Wenn Sie jedoch eine Brute-Force-Lösung wünschen, versuchen Sie Folgendes:
quelle
Die einfachste CMakeLists.txt, die ich aus den Antworten in diesem Thread und einigen Versuchen und Irrtümern herausgearbeitet habe, ist:
Gtest sollte bereits auf Ihrem System installiert sein.
quelle
Nur als Aktualisierung des Kommentars von @ Patricia in der akzeptierten Antwort und des Kommentars von @ Fraser für die ursprüngliche Frage können Sie CMakes verwenden, wenn Sie Zugriff auf CMake 3.11+ haben FetchContent- Funktion aktualisieren .
Die FetchContent-Seite von CMake verwendet Googletest als Beispiel!
Ich habe eine kleine Änderung der akzeptierten Antwort bereitgestellt:
Sie können die
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
Zieleigenschaft der Ziele gtest und gtest_main verwenden, wie sie im Skript goake test CMakeLists.txt festgelegt sind .quelle
target_include_directories
undFetchContent_MakeAvailable(googletest)
stattdessen verwenden. Dadurch wird der Inhalt sowohl ausgefüllt als auch zum Haupt-Build hinzugefügt. CMake FetchContent - weitere InformationenIch beschloss, etwas Generisches ganz schnell zusammenzustellen, um eine andere Vorgehensweise als die zuvor veröffentlichten Antworten zu demonstrieren, in der Hoffnung, dass es jemandem helfen könnte. Folgendes funktionierte für mich auf meinem Mac. Zuerst habe ich Setup-Befehle für gtests ausgeführt. Ich habe gerade ein Skript verwendet, das ich gefunden habe, um alles einzurichten.
Als nächstes habe ich eine einfache Ordnerstruktur erstellt und einige schnelle Klassen geschrieben
Ich habe eine CMakeLists.txt der obersten Ebene für den Ordner utils und eine CMakeLists.txt für den Testordner erstellt
Dies ist die CMakeLists.txt im Testordner
Dann müssen Sie nur noch ein Beispiel für gtest und gtest main schreiben
Probe gtest
Beispiel gtest main
Ich kann dann gtests mit den folgenden Befehlen aus dem Ordner utils kompilieren und ausführen
quelle