Модульные тесты в C++ с помощью CMake и GoogleTest (GTest)
При написании классов, нелишним будет написать для них несколько тестов, покрывающих основные случаи их использования.
В прошлой статье мы рассмотрели создание шаблона класса для работы со строками std::string и std::wstring. Сегодня мы покроем этот класс модульными тестами.
Установка Google Tests (GTest)
Запустим консоль Msys2 и запустим в ней установку пакета
pacman -S mingw-w64-x86_64-gtest
Этого будет достаточно для работы с gtest.
Настройка CMake для работы с модульными тестами (GTest)
Перейдем в папку проекта и создадим файл cmake/tests.cmake.in с содержимым:
find_package(GTest CONFIG REQUIRED)
if (GTest_FOUND)
add_executable(tests tests/test_stringutils.cpp)
target_link_libraries (tests GTest::gtest GTest::gtest_main)
enable_testing()
add_test(NAME StringUtilsTest COMMAND tests)
message("=== GoogleTest found and setup complete")
endif()Здесь всё просто, мы пытаемся найти установленный Gtest и если он найден, добавляем новый target - tests в который включаем наш файл с тестом. Включаем тестирование, добавляем тесты и выводим сообщение.
Создадим папку для тестов
mkdir testsСоздадим файл
tests/test_stringutils.cpp с содержимым:
#include "../src/stringutils.h"
#include <gtest/gtest.h>
TEST(TestStringUtils, TrimTestsEn) {
StringUtils<std::string> s;
std::string testStr;
testStr = " TEST STRING";
EXPECT_EQ(s.ltrim(testStr), "TEST STRING");
testStr = "TEST STRING ";
EXPECT_EQ(s.rtrim(testStr), "TEST STRING");
testStr = " TEST STRING ";
EXPECT_EQ(s.trim(testStr), "TEST STRING");
}
TEST(TestStringUtils, TrimTestsRu) {
StringUtils<std::wstring> s;
std::wstring testStr;
testStr = L" ПРИВЕТ МИР";
EXPECT_EQ(s.ltrim(testStr), L"ПРИВЕТ МИР");
testStr = L"ПРИВЕТ МИР ";
EXPECT_EQ(s.rtrim(testStr), L"ПРИВЕТ МИР");
testStr = L" ПРИВЕТ МИР ";
EXPECT_EQ(s.trim(testStr), L"ПРИВЕТ МИР");
}
TEST(TestStringUtils, SplitTestsEn) {
StringUtils<std::string> s;
std::string testStr;
testStr = "HELLO MY PERFECT WORLD";
StringUtils<std::string>::strlist result;
result.insert(result.end(), "HELLO");
result.insert(result.end(), "MY");
result.insert(result.end(), "PERFECT");
result.insert(result.end(), "WORLD");
EXPECT_EQ(s.split(testStr, " "), result);
}
TEST(TestStringUtils, SplitTestsRu) {
StringUtils<std::wstring> s;
std::wstring testStr;
testStr = L"ПРИВЕТ МОЙ НОВЫЙ МИР";
StringUtils<std::wstring>::strlist result;
result.insert(result.end(), L"ПРИВЕТ");
result.insert(result.end(), L"МОЙ");
result.insert(result.end(), L"НОВЫЙ");
result.insert(result.end(), L"МИР");
EXPECT_EQ(s.split(testStr, L" "), result);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}В этом файле мы просто создаем экземпляр класса, подготавливаем данные для тестирования и данные для проверки результатов тестов. В нашем случаем функция EXPECT_EQ производит сравнение двух значений и если они не совпадает прерывает тестирование с ошибкой.
Добавим в конец файла CMakeLists.txt строки:
# настраиваем модульные тесты
include(${PROJECT_SOURCE_DIR}/cmake/tests.cmake.inЗапустим сборку:
cmake -S . -B buildЕсли не возникло проблем с нахождением GTest мы увидим строку:
=== GoogleTest found and setup completeЗапустим сборку:
cmake --build buildНа этот раз помимо файла cppapp.exe будет собран исполняемый файл для наших тестов tests.exe.
Запуск тестов
Запустим тест:
build\tests.exeРезультат:
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from TestStringUtils
[ RUN ] TestStringUtils.TrimTestsEn
[ OK ] TestStringUtils.TrimTestsEn (0 ms)
[ RUN ] TestStringUtils.TrimTestsRu
[ OK ] TestStringUtils.TrimTestsRu (0 ms)
[ RUN ] TestStringUtils.SplitTestsEn
[ OK ] TestStringUtils.SplitTestsEn (0 ms)
[ RUN ] TestStringUtils.SplitTestsRu
[ OK ] TestStringUtils.SplitTestsRu (0 ms)
[----------] 4 tests from TestStringUtils (18 ms total)
[----------] Global testenvironment tear-down
[==========] 4 tests from 1 test suite ran. (35 ms total)
[ PASSED ] 4 tests.Запуск тестов с помощью ctest
В составе CMake находится программа ctest, которая позволяет запускать тесты.
Для запуска тестов с помощью этой программы нужно сначала собрать программу с помощью CMake, а потом запустить:
cd build
ctestРезультат:
Test project C:/projects/string_utils/build
Start 1: StringUtilsTest
1/1 Test #1: StringUtilsTest .................. Passed 0.02 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.02 secЗаключение
Сегодня мы рассмотрели создание модульных тестов для класса StringUtils с использованием CMake и Google Tests:
Установили GTest с помощью Msys2;
Добавили настройки в CMake для подключения и работы с GTest;
Создали папку тестов и добавили в него код модульного теста;
Собрали тесты с помощью CMake;
Запустили тесты с помощью исполняемого файла и ctest.
Добавить комментарий