J'ai récemment été convaincu d'utiliser CMake pour compiler mes projets C ++, et j'aimerais maintenant commencer à écrire des tests unitaires pour mon code. J'ai décidé d'utiliser l'utilitaire Google Test pour vous aider, mais j'ai besoin d'aide pour démarrer.
Toute la journée, j'ai lu divers guides et exemples dont le Primer , une introduction chez IBM et quelques questions sur SO ( ici et ici ) ainsi que d'autres sources dont j'ai perdu la trace. Je me rends compte qu'il y en a beaucoup là-bas, mais d'une manière ou d'une autre, j'ai encore des difficultés.
J'essaie actuellement d'implémenter le test le plus basique, pour confirmer que j'ai compilé / installé gtest correctement et que cela ne fonctionne pas. Le seul fichier source (testgtest.cpp) est tiré presque exactement de cette réponse précédente:
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
et mon CMakeLists.txt associé est le suivant:
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
)
Notez que j'ai choisi de créer un lien avec gtest_main au lieu de fournir le principal à la fin du fichier cpp car je pense que cela me permettra de faire évoluer les tests plus facilement vers plusieurs fichiers.
Lors de la construction du fichier .sln généré (dans Visual C ++ 2010 Express), j'obtiens malheureusement une longue liste d'erreurs du formulaire
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)
ce qui, je pense, signifie que je ne parviens pas à établir une liaison avec les bibliothèques gtest. Je me suis assuré que lors de la liaison avec les bibliothèques de débogage, j'ai ensuite essayé de construire en mode débogage.
ÉDITER
Après avoir creusé davantage, je pense que mon problème est lié au type de bibliothèque dans laquelle je construis gtest. Lors de la construction de gtest avec CMake, si elle BUILD_SHARED_LIBS
n'est pas cochée, et que je lie mon programme à ces fichiers .lib, j'obtiens les erreurs mentionnées ci-dessus. Cependant, si BUILD_SHARED_LIBS
est coché, je produis un ensemble de fichiers .lib et .dll. Lors de la liaison avec ces fichiers .lib, le programme se compile, mais lors de l'exécution se plaint qu'il ne peut pas trouver gtest.dll.
Quelles sont les différences entre une bibliothèque SHARED
et une SHARED
bibliothèque not , et si je choisis non partagé, pourquoi cela ne fonctionne-t-il pas? Y a-t-il une option dans le CMakeLists.txt pour mon projet qui me manque?
la source
ExternalProject_Add
plutôt queadd_subdirectory
. Voir cette réponse pour plus de détails.enable_testing()
-on?Réponses:
La solution consistait à placer le répertoire source gtest comme un sous-répertoire de votre projet. J'ai inclus le CMakeLists.txt de travail ci-dessous s'il est utile à quiconque.
la source
pthread
aux bibliothèques liées, en changeant l'avant-dernière ligne entarget_link_libraries(runUnitTests gtest gtest_main pthread)
make test
pour exécuter les tests, ou exécuter àctest
partir du répertoire de construction. Exécutezctest -V
pour voir la sortie du test google ainsi que lactest
sortie.Voici un exemple de travail complet que je viens de tester. Il télécharge directement à partir du Web, soit une archive tar fixe, soit le dernier répertoire de subversion.
la source
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
place de l'URLhttps://github.com/google/googletest/archive/release-1.10.0.zip
Vous pouvez obtenir le meilleur des deux mondes. Il est possible d'utiliser
ExternalProject
pour télécharger la source gtest puis de l'utiliseradd_subdirectory()
pour l'ajouter à votre build. Cela présente les avantages suivants:Utilisé de manière normale, ExternalProject ne fera pas le téléchargement et le déballage au moment de la configuration (c'est-à-dire lorsque CMake est exécuté), mais vous pouvez le faire avec juste un peu de travail. J'ai écrit un article de blog sur la façon de faire cela, qui comprend également une implémentation généralisée qui fonctionne pour tout projet externe utilisant CMake comme système de construction, pas seulement gtest. Vous pouvez les trouver ici:
Mise à jour: cette approche fait désormais également partie de la documentation googletest .
la source
Très probablement, la différence dans les options du compilateur entre votre binaire de test et la bibliothèque de test Google est à blâmer sur de telles erreurs. C'est pourquoi il est recommandé d'intégrer Google Test sous la forme source et de le construire avec vos tests. C'est très facile à faire dans CMake. Vous
ADD_SUBDIRECTORY
appelez simplement avec le chemin d'accès à la racine gtest et vous pouvez ensuite utiliser les cibles de bibliothèque publique (gtest
etgtest_main
) définies ici. Il y a plus d'informations générales dans ce fil CMake dans le groupe googletestframework.[modifier] L'
BUILD_SHARED_LIBS
option n'est efficace que sur Windows pour le moment. Il spécifie le type de bibliothèques que vous souhaitez que CMake crée. Si vous le définissez surON
, CMake les construira en tant que DLL par opposition à des bibliothèques statiques. Dans ce cas, vous devez construire vos tests avec -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 et copier les fichiers DLL produits par CMake dans le répertoire avec votre binaire de test (CMake les place par défaut dans un répertoire de sortie séparé). À moins que gtest dans la bibliothèque statique ne fonctionne pour vous, il est plus facile de ne pas définir cette option.la source
En effet, vous devez ajouter -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 aux définitions du compilateur dans votre projet si vous souhaitez utiliser gtest comme bibliothèque partagée.
Vous pouvez également utiliser les bibliothèques statiques, à condition de les compiler avec l'option gtest_force_shared_crt activée pour éliminer les erreurs que vous avez vues.
J'aime la bibliothèque mais l'ajouter au projet est une vraie douleur. Et vous n'avez aucune chance de le faire correctement à moins de creuser (et de pirater) les fichiers cmake gtest. La honte. En particulier, je n'aime pas l'idée d'ajouter gtest comme source. :)
la source
L'OP utilise Windows, et un moyen beaucoup plus simple d'utiliser GTest aujourd'hui est avec vcpkg + cmake.
Installez vcpkg selon https://github.com/microsoft/vcpkg et assurez-vous que vous pouvez exécuter à
vcpkg
partir de la ligne cmd. Prenez note du dossier d'installation de vcpkg, par exemple.C:\bin\programs\vcpkg
.Installez gtest en utilisant
vcpkg install gtest
: cela téléchargera, compilera et installera GTest.Utilisez un CmakeLists.txt comme ci-dessous: notez que nous pouvons utiliser des cibles au lieu d'inclure des dossiers.
Exécutez cmake avec: (modifiez le dossier vcpkg si nécessaire et assurez-vous que le chemin d'accès au fichier de chaîne d'outils vcpkg.cmake est correct)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:\bin\programs\vcpkg\scripts\buildsystems\vcpkg.cmake
et construisez en utilisant
cmake --build build
comme d'habitude. Notez que vcpkg copiera également le fichier gtest (d) .dll / gtest (d) _main.dll requis du dossier d'installation vers les dossiers Debug / Release.Testez avec
cd build & ctest
.la source
Vos solutions et celles de VladLosevs sont probablement meilleures que les miennes. Si vous voulez une solution de force brute, cependant, essayez ceci:
la source
Le CMakeLists.txt le plus simple que j'ai distillé à partir des réponses dans ce fil et des essais et erreurs est:
Gtest devrait déjà être installé sur votre système.
la source
Tout comme une mise à jour du commentaire de @ Patricia dans la réponse acceptée et du commentaire de @ Fraser pour la question d'origine, si vous avez accès à CMake 3.11+, vous pouvez utiliser la fonction FetchContent de CMake .
La page FetchContent de CMake utilise googletest comme exemple!
J'ai fourni une petite modification de la réponse acceptée:
Vous pouvez utiliser la
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
propriété target des cibles gtest et gtest_main telles qu'elles sont définies dans le script google test CMakeLists.txt .la source
target_include_directories
et utiliser à laFetchContent_MakeAvailable(googletest)
place. Cela remplira le contenu et l'ajoutera à la construction principale. CMake FetchContent - plus d'infosJ'ai décidé de jeter quelque chose de générique ensemble très rapidement, démontrant une façon différente de le faire que les réponses précédemment publiées, dans l'espoir que cela puisse aider quelqu'un. Ce qui suit a fonctionné pour moi sur mon mac. Tout d'abord, j'ai exécuté des commandes de configuration pour gtests. Je viens d'utiliser un script que j'ai trouvé pour tout configurer.
Ensuite, j'ai créé une structure de dossiers simple et écrit quelques classes rapides
J'ai créé un CMakeLists.txt de niveau supérieur pour le dossier utils et un CMakeLists.txt pour le dossier tests
Il s'agit du CMakeLists.txt dans le dossier tests
Ensuite, il ne reste plus qu'à écrire un exemple de gtest et gtest main
échantillon gtest
échantillon gtest main
Je peux ensuite compiler et exécuter gtests avec les commandes suivantes à partir du dossier utils
la source