Я пытаюсь структурировать свой проект, чтобы включить производственные источники (во src
вложенной папке) и тесты (во test
вложенной папке). Я использую CMake для создания этого. В качестве минимального примера у меня есть следующие файлы:
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 - использует sqr, не имеет особого значения
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));
}
Несколько вопросов:
- Имеет ли смысл эта структура? Каковы лучшие практики при структурировании этого кода? (Я прихожу с C # и java, и там в некотором смысле проще)
- Мне не нравится то, что мне нужно перечислять все файлы из
src
папки вtest/CMakeLists.txt
файле. Если бы это был библиотечный проект, я бы просто связал библиотеку. Есть ли способ избежать перечисления всех файлов cpp из другого проекта? - Какие линии
enable_testing()
и чтоadd_test(MyTest test)
делать? Я не заметил никакого эффекта. Как запустить тесты из CMake (или CTest)? - До сих пор я просто запускал
cmake .
в корневой папке, но это создавало беспорядок с временными файлами повсюду. Как мне получить разумную структуру результатов компиляции?
c++
unit-testing
boost
cmake
boost-test
Грзенио
источник
источник
Ответы:
Для вопросов 1 и 2 я бы порекомендовал создать библиотеку из ваших файлов, не являющихся тестовыми, за исключением main.cpp (в данном случае только src / sqr.cpp и src / sqr.h), и тогда вы можете избежать перечисления (и, что более важно, повторная компиляция) все исходники дважды.
Для вопроса 3 эти команды добавляют тест под названием «MyTest», который вызывает ваш исполняемый «тест» без каких-либо аргументов. Однако, поскольку вы добавили эти команды в test / CMakeLists.txt, а не в файл CMakeLists.txt верхнего уровня, вы можете вызывать тест только из подкаталога test вашего дерева сборки (попробуйте
cd test && ctest -N
). Если вы хотите, чтобы тест запускался из каталога сборки верхнего уровня, вам нужно будет вызватьadd_test
из CMakeLists.txt верхнего уровня. Это также означает, что вам нужно использовать более подробную форму,add_test
поскольку ваш тестовый exe не определен в том же файле CMakeLists.txt.В вашем случае, поскольку вы запускаете cmake в корневой папке, ваше дерево сборки и ваше исходное дерево одно и то же. Это известно как сборка из исходных кодов и не идеально, что приводит к вопросу 4.
Предпочтительный метод создания дерева сборки - выполнить сборку вне исходного кода, то есть создать каталог где-нибудь за пределами вашего исходного дерева и выполнить cmake оттуда. Даже создание каталога «сборки» в корне вашего проекта и его выполнение
cmake ..
обеспечат чистую структуру, которая не будет мешать вашему дереву исходных текстов.И наконец, не следует называть исполняемые файлы «тестовыми» (с учетом регистра). О причинах см. Этот ответ .
Чтобы добиться этих изменений, я бы сделал следующее:
CMakeLists.txt:
src / CMakeLists.txt:
test / CMakeLists.txt:
источник
project (TEST)
- см. Cmake.org/cmake/help/v3.6/variable/PROJECT-NAME_SOURCE_DIR.htmlМне нравится пример @Fraser, но я бы использовал команду add_test в файле test / CMakeLists.txt и использовал enable_testing перед add_subdirectory (test).
Таким образом, вы можете запускать тесты из каталога сборки верхнего уровня, указывая тесты в файле test / CMakeLists.txt.
Результат будет выглядеть так (я повторно использовал пример @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)
источник
ctest -N
пока вы не дадите подсказку о включении тестирования перед добавлением подкаталога.