e7db3a9f90 | ||
---|---|---|
includes | ||
src | ||
tests | ||
.gitignore | ||
CMakeLists.txt | ||
conanfile.txt | ||
readme.md |
readme.md
Базовая настройка тестирования.
Используемые технологии
- C++11
- CMake
- GTest (Google test framework for C++)
- Conan
Структура проекта
- Project/
-- build/
--- <caches>
--- bin/
---- program
-- include/
--- algo.h
--- algo.c
-- src/
--- main.c
-- tests/
--- test.cpp
- conanfile.txt
- CMakeLists.txt
conanfile
Для подключения тестового фреймворка используется система менеджмента артефактов Conan, которая позволяет осуществлять подключение заранее скомпилированных библиотек без необходимости их установки на ОС разработчика. Подключение осуществляется описанием корректных настроек в файле conanfile.txt:
[requires]
gtest/cci.20210126
[generators]
cmake
Таким образом, будет подключена последняя на момент написания данного документа сборка фреймворка тестирования.
sources
Исходные коды проекта разделены на две части: собственно исходники и включаемые файлы. Исходники - это код самой программы, использующей алгоритмы, описанные во включаемых заголовочных файлах.
src/main.c
В файле с программой подключается файл с тестируемым алгоритмом, который используется в коде программы:
#include <stdio.h>
#include "../include/algo.h"
void swap(char* a, char* b);
int main(int argc, const char** argv) {
char a = -11;
char b = 15;
printf("a=%d; b=%d\n", a, b);
swap(&a, &b);
printf("a=%d; b=%d\n", a, b);
return 0;
}
Выводом данного кода будет:
user@debian: ./build/bin/prog
a=-11; b=15
a=15; b=-11
include/algo.h
Подключаемый в код программ и тестов заголовочный файл должен содержать только одно объявление функций:
#ifndef algos
#define algos
void swap(char* a, char* b);
#endif
include/algo.c
файл с реализацией лаконичен:
#include "algos.h"
void swap(char* a, char* b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
tests
Тесты описываются в отдельном файле, из которого будет собран бинарный файл. Важно, что фреймворк работает только с С++11 или новее, поэтому использовать более старый стандарт не получится, а исходные файлы на С нужно включать в секции extern "C"
. Каждый тест описывается в специальной макрофункции TEST
в параметрах которой указывается детальное название теста. В данном примере будет использоваться только один ассерт - EXPECT_EQ
, который проверяет значение переданной первым аргументом переменной на равенство второму аргументу
tests/test.cpp
#include <gtest/gtest.h>
#include <iostream>
extern "C" {
#include "../includes/algos.h"
}
TEST(HelloTest, WeTestHere) {
char a = -11;
char b = 15;
swap(&a, &b);
EXPECT_EQ(a, 15);
EXPECT_EQ(b, -11);
}
TEST(AnotherTest, WeTestThere) {
char a = -11;
char b = -11;
swap(&a, &b);
EXPECT_EQ(a, -11);
EXPECT_EQ(b, -11);
}
CMake
Сборщик CMake описывает правила, по которым будет сформировал Makefile для дальнейшей сборки утилитой GNU Automake или Ninja. В файл настроек необходимо включить строки подключения артефактов Conan, поскольку мы используем готовую сборку фреймворка тестирования, а не устанавливаем его на компьютер. Также в скрипте указывается два исполняемых файла - для сборки программы и тестов, соответственно.
cmake_minimum_required(VERSION 3.5)
project(BasicC)
enable_testing()
# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)
# conan dependencies
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
# test executable
add_executable(check tests/test.cpp include/algo.h include/algo.c)
target_link_libraries(check ${CONAN_LIBS} gtest_main)
# let make know we use tests
include(GoogleTest)
gtest_discover_tests(check)
# application executable
add_executable(prog src/main.c include/algo.h include/algo.c)
Запуск
Запуск осуществляется из папки build
, соответственно:
conan install ..
(установить зависимости conan, описанные в файле папкой выше)cmake ..
(подготовить Makefile по правилам из файла папкой выше)make
(собрать проект)ctest
(запустить тесты)./bin/prog
(запустить программу) В результате запуска тестов получится следующий вывод:
Test project /home/user/Documents/book-c-basic/build
Start 1: HelloTest.WeTestHere
1/2 Test #1: HelloTest.WeTestHere ............. Passed 0.01 sec
Start 2: AnotherTest.WeTestThere
2/2 Test #2: AnotherTest.WeTestThere .......... Passed 0.00 sec
100% tests passed, 0 tests failed out of 2
Total Test time (real) = 0.01 sec