J'essaie de structurer mon projet pour inclure les sources de production (dans le sous-dossier src
) et les tests (dans le sous-dossier test
). J'utilise CMake pour construire cela. Comme exemple minimal, j'ai les fichiers suivants:
CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)
add_subdirectory (test)
src/CMakeLists.txt:
add_executable (demo main.cpp sqr.cpp)
src/sqr.h
#ifndef SQR_H
#define SQR_H
double sqr(double);
#endif // SQR_H
src/sqr.cpp
#include "sqr.h"
double sqr(double x) { return x*x; }
src/main.cpp - utilise sqr, cela n'a pas d'importance
test/CMakeLists.txt:
find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src)
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)
add_executable (test test.cpp ${TEST_SOURCE_DIR}/src/sqr.cpp)
target_link_libraries(test
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
)
enable_testing()
add_test(MyTest test)
test/test.cpp:
#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>
#include "sqr.h"
BOOST_AUTO_TEST_CASE(FailTest)
{
BOOST_CHECK_EQUAL(5, sqr(2));
}
BOOST_AUTO_TEST_CASE(PassTest)
{
BOOST_CHECK_EQUAL(4, sqr(2));
}
Quelques questions:
src
du fichier test/CMakeLists.txt
. S'il s'agissait d'un projet de bibliothèque, je lierais simplement la bibliothèque. Y a-t-il un moyen d'éviter de lister tous les fichiers cpp de l'autre projet?enable_testing()
et add_test(MyTest test)
? Je n'ai vu aucun effet. Comment puis-je exécuter les tests à partir de CMake (ou CTest)?cmake .
Dans le dossier racine, mais cela a créé un désordre avec des fichiers temporaires partout. Comment puis-je obtenir les résultats de la compilation dans une structure raisonnable?Pour les questions 1 et 2, je vous recommanderais de créer une bibliothèque à partir de vos fichiers non-test en excluant le fichier main.cpp (dans ce cas, simplement src/sqr.cpp et src/sqr.h), afin d'éviter toute liste (et plus important encore). recompiler) toutes les sources deux fois.
Pour la question 3, ces commandes ajoutent un test appelé "MyTest" qui appelle votre "test" exécutable sans aucun argument. Cependant, puisque vous avez ajouté ces commandes pour tester/CMakeLists.txt et non votre CMakeLists.txt de niveau supérieur, vous ne pouvez appeler le test que dans le sous-répertoire "test" de votre arborescence de génération (try cd test && ctest -N
). Si vous souhaitez que le test puisse être exécuté à partir de votre répertoire de construction de niveau supérieur, vous devez appeler add_test
du fichier CMakeLists.txt de niveau supérieur. Cela signifie également que vous devez utiliser la forme la plus verbeuse de add_test
puisque votre test exe n'est pas défini dans le même fichier CMakeLists.txt
Dans votre cas, puisque vous exécutez cmake dans le dossier racine, votre arborescence de construction et votre arborescence source sont identiques. Ceci est connu comme une construction dans la source et n'est pas idéal, ce qui conduit à la question 4.
La méthode privilégiée pour générer l’arbre de construction consiste à créer un répertoire hors source, c’est-à-dire créer un répertoire quelque part en dehors de votre arborescence source et exécuter cmake à partir de cet emplacement. Même en créant un répertoire "build" à la racine de votre projet et en exécutant cmake ..
fournirait une structure propre qui n’interférerait pas avec votre arbre source.
Un dernier point est d'éviter d'appeler les exécutables "test" (sensible à la casse). Pour des raisons, voir cette réponse .
Pour réaliser ces changements, je procéderais comme suit:
CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)
src/CMakeLists.txt:
add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)
test/CMakeLists.txt:
find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
${Boost_INCLUDE_DIRS}
)
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
Sqr
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
)
J'aime l'exemple de @Fraser mais j'utiliserais la commande add_test dans le test/CMakeLists.txt et utiliser enable_testing avant add_subdirectory (test).
De cette façon, vous pouvez exécuter vos tests à partir du répertoire de construction de niveau supérieur tout en spécifiant vos tests dans le fichier test/CMakeLists.txt.
Le résultat ressemblerait à ceci (j'ai réutilisé l'exemple de @Fraser):
CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)
enable_testing ()
add_subdirectory (test)
src/CMakeLists.txt
add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)
test/CMakeLists.txt
find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
${Boost_INCLUDE_DIRS}
)
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
Sqr
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
)
add_test (NAME MyTest COMMAND Test)