Думаю что большинство C++ разработчиков так или иначе сталкивались с CMake, в то же время что такое CTest и как с его помощью можно автоматизировать модельное тестирование знают далеко не все.
Для того, что бы показать как можно использовать CMake и CTest вместе, я в качестве примера создал маленькую библиотечку, состоящую из пары строк кода, которое умеет складывать и делить Кроме приложений CMake и CTest, понадобится какая-либо UnitTest библиотека (в данном примере я взял Boost.Test, хотя, можно взять и GoogleTest). Тут стоит обратить внимание на то, что CTest не является фрэймворком для написания тестов. CTest – это приложение для запуска тестов и, если это необходимо, отправки результатов в какое-либо из поддерживаемых хранилищ.
Структура директорий с тестовом приложении будет следующая:
./test
./test/main.cpp
./test/CMakeLists.txt
./include
./include/calc.h
./src
./src/CMakeLists.txt
./src/calc.cpp
./CMakeLists.txt
Таким образом, создаем один корневой CMakeLists и по одному CMakeLists файлу для описания сборки самой библиотеки и тестов.
project(AutoUnitTests)
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/bin
CACHE PATH
"Single Directory for all"
)
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/bin
CACHE PATH
"Single Directory for all"
)
SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/lib
CACHE PATH
"Single Directory for all"
)
enable_testing()
find_package(Boost REQUIRED)
include_directories(include)
add_subdirectory( src build/src )
add_subdirectory( test build/test )
Первые три SET команды не обязательны, просто я не люблю когда в процессе сборки куча промежуточных файлов помещается в корневую директорию. А вот наличие команды enable_testing в корневом CMakeLists файле на оборот обязательно, если ее перенести в CMakeLists из директории test, то работать это не будет.
Следующим шагом будет создание CMakeLists файла в директории src, честно сказать, он из себя не малейшего интереса не представляет:
set( Calc_source calc.cpp )
add_library( calc STATIC ${Calc_source} )
И последний файл, в директории test:
find_package (Boost COMPONENTS unit_test_framework REQUIRED)
set(test1_source main.cpp)
add_executable(test1 ${test1_source})
target_link_libraries(test1 ${Boost_LIBRARIES} calc)
add_test(NAME Test1 COMMAND test1)
Единственным отличаем от обычного CMakeLists файла будет команда add_test, в которую передается имя теста и то, какую команду необходимо выполнить для его запуска. Т.е. данная команда вполне может выглядеть и так:
Теперь, тесты на выполнение можно запускать при помощи команды make test и результат будет выглядеть следующим образом:
Test project /home/astavonin/Projects/AutoUnitTest
Start 1: Test1
1/1 Test #1: Test1 ............................ Passed 0.03 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.56 sec
Если же добавить еще один тест, который должен провалиться, то результаты будут несколько иные:
Test project /home/astavonin/Projects/AutoUnitTest
Start 1: Test1
1/2 Test #1: Test1 ............................ Passed 0.00 sec
Start 2: Test2
2/2 Test #2: Test2 ............................***Failed 0.00 sec
50% tests passed, 1 tests failed out of 2
Total Test time (real) = 0.46 sec
The following tests FAILED:
2 - Test2 (Failed)
Errors while running CTest
Консольный вывод тестовых приложений будет сохранен в директории ./Testing/Temporary.
Пример полностью можно скачать тут.
Только разбираюсь с CMake, потому спасибо за подсказку, буду пробовать на GTest. Шрифт вырвиглазен.
Да, шрифт был не очень. Давно хотел сменить. Иногда критические комментарии служат хорошим мотиватором для изменений
А можно ли как-то сделать так, чтобы output из тестов (я использую gtest, выдается статистика по каждому тесту) не “проглатывался” при запуске make test?
То есть, вместо
Start 1: test1
1/1 Test #1: test1 ……………………….***Exception: SegFault 0.21 sec
0% tests passed, 1 tests failed out of 1
было бы
[==========] Running 14 tests from 4 test cases.
[———-] Global test environment set-up.
…
[ FAILED ] BucketsTestFixture.TestNonZeroCount (0 ms)
[ RUN ] BucketsTestFixture.TestClear
etc. ?
Ответ найден: make test ARGS=”-V”
>> Таки образом, создаем один к
где-то в одних из первых абзацев. буква “м” пропущена?
Спасибо
Добрый день, Александр. Извините за детский вопрос. Но я часами мучаюсь, скачал ваш архив еще. А в какой директории я должен быть, что бы ввести эту команду “make test”?
В корневой папке проекта. Но сначала надо выполнить просто `make`, который сгенерирует нужные файлы, и только потом `make test`. Ну и это для *NIX будет только работать, для Windows вместо Makefile придется писать bat-ник.
Посту 7 лет, а актуальность на высоте! 🙂 Спасибо за архив с примером: хорошая затравка для нового проекта! 🙂
Пожалуйста, рад что до сих пор полезно
Не могу понять, как нескольно тестов разом добавить? Неужели каждый раз надо писать еще раз ‘add_test(…)’?