Хабрахабр

Полное руководство по CMake. Часть третья: Тестирование и пакетирование

Строго рекомендуется прочитать первую и вторую части руководства во избежание непонимания синтаксиса и принципа работы CMake. Данная статья повествует о тестировании и пакетировании программ при помощи CMake — гибкого и универсального набора утилит для разработки различных программных продуктов.

Экспериментируйте с исходным кодом, меняя существующие команды и добавляя новые. Ниже приведены примеры использования языка CMake, по которым Вам следует попрактиковаться. Чтобы запустить данные примеры, установите CMake с официального сайта.

Данную возможность весьма легко использовать — достаточно лишь написать несколько команд в привычном CMakeLists.txt, а затем запустить тесты посредством ctest или make test. Как было сказано ранее, CMake поддерживает автоматическое тестирование программ. В Вашем распоряжении присутствует проверка вывода программ, динамический анализ памяти и многое другое.

Исходный файл Multiply.c содержит следующий код: Мы рассмотрим процесс тестирования программы на конкретном примере.

#include <stdio.h>
#include <stdlib.h>
#define ARG_COUNT 3 int main(const int argc, const char *argv[]) const int first = atoi(argv[1]); const int second = atoi(argv[2]); printf("The result is: %d\n", first * second); return EXIT_SUCCESS;
}

Обратите внимание, что возможна также ситуация возникновения ошибки, если реальное число аргументов не удоволетворяет ожидаемому: в таком случае в поток ошибок будет выведено Error!. Данный код выводит результат перемножения двух аргументов в консоль.

В том же каталоге находится файл CMakeLists.txt с описанием процесса сборки, содержащий приведённый ниже код:

cmake_minimum_required(VERSION 3.0)
project(MyProgram)
add_executable(Multiply Multiply.c) set(MULTIPLY_TIMEOUT 1) # Включить поддержку тестирования:
enable_testing() # Добавить тесты:
add_test(FirstTest Multiply 15 207)
add_test(SecondTest Multiply -54 -785)
add_test(ThirdTest Multiply 85234) # Установить поведение тестов:
set_tests_properties(FirstTest SecondTest ThirdTest
PROPERTIES TIMEOUT ${MULTIPLY_TIMEOUT}) set_tests_properties(FirstTest PROPERTIES
PASS_REGULAR_EXPRESSION "The result is: 3105"
FAIL_REGULAR_EXPRESSION "Error!") set_tests_properties(SecondTest PROPERTIES
PASS_REGULAR_EXPRESSION "The result is: 42390"
FAIL_REGULAR_EXPRESSION "Error!") set_tests_properties(ThirdTest PROPERTIES
PASS_REGULAR_EXPRESSION "Error!")

Первые четыре команды должны быть вам знакомы с предыдущей статьи, а следующая команда enable_testing вызывает ряд вопросов. Рассмотрим всё по порядку. По существу, данная команда лишь уведомляет CMake о Вашем намерении протестировать программу, попутно генерируя некоторые конфигурационные файлы, о существовании которых Вам знать не обязательно.

Краткая форма данной команды первым аргументом принимает наименование теста, а последующие аргументы образуют команду оболочки для запуска теста. Следующие три команды add_test добавляют тесты к текущему проекту.

После списка наименований тестов следует ключевое слово PROPERTIES, сигнализирующее о начале списка свойств, имеющих вид <название свойства> <новое значение> и задаваемых для выбранных тестов. Череда команд set_tests_properties устанавливает поведение отдельно взятых тестов. Полный список доступных свойств находится тут.

Для всех тестов задаётся максимальное время исполнения в одну секунду свойством TIMEOUT, а затем для последующих тестов устанавливается ожидаемый вывод свойствами PASS_REGULAR_EXPRESSION и FAIL_REGULAR_EXPRESSION (например, если происходит совпадение с регулярным выражением The result is: 3105, то выполнение теста FirstTest продолжается, а в случае совпадения с выражением Error! тест останавливается и считается неудавшимся).

В общем случае, включение модуля более универсально, однако между ними всё же есть различие. Существует аналог команды enable_testing — это включение модуля CTest посредством команды include.

Она должна находится в корневом CMakeLists.txt, так как CTest ожидает файл тестирования в корне сборки. Команда enable_testing включает тестирование для текущего каталога, а также для всех последующих.

Таким образом, при использовании данной команды разумно описывать процесс тестирования подобным образом: Включение модуля CTest конфигурирует проект для тестирования посредством CTest/CDash, а также автоматически определяет опцию BUILD_TESTING, принимающую истину при возможности проведения тестирования (по умолчанию — ON).

if(BUILD_TESTING) add_test(FirstTest Test 1) add_test(SecondTest Test 2) add_test(ThirdTest Test 3) # Следующие команды...
endif()

&& cmake --build . Чередой команд cmake . Командой ctest -R <RegularExpression> исполняется набор тестов, удоволетворяющих заданному регулярному выражению. && ctest . запускаются на выполнение все три теста. Например, команда ctest -R ThirdTest запускает лишь третьй тест.

Для создания пакета исходных файлов, библиотек и исполняемых файлов Вам осталось лишь описать установку необходимых файлов с помощью команды install, а затем включить модуль CPack командой include:

# Установить исполняемый файл "Multiply" в директорию "bin":
install(TARGETS Multiply DESTINATION bin) # Задать некоторые характеристики пакета:
set(CPACK_PACKAGE_NAME "Multiply")
set(CPACK_PACKAGE_VENDOR "MyCompany")
set(CPACK_PACKAGE_CONTACT "https://myprojectsite.org")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "mycontacts@gmail.com")
set(CPACK_PACKAGE_DESCRIPTION "The most stupid program ever written") # Задать используемый генератор пакетов:
set(CPACK_GENERATOR "DEB") # Включить стандартный модуль "CPack":
include(CPack)

Без написания команд установки генерация пакетов невозможна. В данном случае, команда install уведомляет генератора пакетов о каталоге установки цели Multiply.

На самом деле, существует обилие подобных переменных, должным образом оформляющих пакеты. Далее перечисляются характеристики пакета заданием нескольких переменных. Список переменных, общих для всех генераторов пакетов, доступен здесь. Большинство из них не обязательны, однако некоторые генераторы пакетов требуют их определения.

В данном случае она принимает значение DEB, следовательно, в корневом каталоге обзорного приложения сгенерируется debian-пакет. Обязательно определение переменной CPACK_GENERATOR — она является списком генераторов пакетов, вызываемых утилитой cpack.

Наконец, подключается модуль CPack, конфигурирующий будущий пакет проекта, используя ранее определённые переменные и команду установки исполняемого файла, а также добавляющий две цели сборки — package и package_source (соответственно бинарная сборка и сборка исходных кодов).

&& cmake --build . Чередой команд cmake . --target package запускается на выполнение выбранный генератор для создания бинарного пакета, а команды cmake . && cmake --build . && cmake --build . && cmake --build . --target package_source генерируют пакет исходных кодов прямо в корневом каталоге.

Разбор исходных файлов CMake популярного проекта выйдет до нового года в виде отдельной статьи (предлагайте варианты в комментариях). Статья вышла на свет с опозданием из-за неотложных обстоятельств, но я надеюсь, что Вы её оцените не меньше предыдущих. Удачи!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть