Понедельник, 29.12.2025 15:53

Модульные тесты в C++ с помощью CMake и GoogleTest (GTest)

Модульные тесты в 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.

Категория C++

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

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 80