Тестирование в C++: фреймворки и инструменты для проверки кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Тестирование в C++: обзор фреймворков и инструментов

Тестирование — неотъемлемая часть профессиональной разработки на C++. В отличие от языков с динамической типизацией, C++ требует особого внимания к управлению памятью, RAII и шаблонным метапрограммам. Без качественных тестов даже небольшой рефакторинг может привести к трудноуловимым ошибкам. В этой статье мы разберём основные фреймворки для модульного тестирования в C++, их особенности и примеры использования.

Зачем тестировать C++ код?

Основные причины внедрения тестирования:

  • Безопасность рефакторинга — тесты фиксируют корректное поведение до изменений.
  • Документация — тесты показывают, как использовать API.
  • Обнаружение регрессий — автоматическая проверка после каждого коммита.
  • Валидация граничных случаев — работа с nullptr, пустыми контейнерами, переполнением.

Популярные фреймворки для C++

1. Google Test (gtest)

Самый распространённый фреймворк от Google. Поддерживает автоматическую регистрацию тестов, макросы ASSERT_* и EXPECT_*, параметризованные тесты, моки через Google Mock.

#include <gtest/gtest.h>

int add(int a, int b) { return a + b; }

TEST(AdditionTest, PositiveNumbers) {
    EXPECT_EQ(add(2, 3), 5);
    EXPECT_EQ(add(0, 0), 0);
}

TEST(AdditionTest, NegativeNumbers) {
    EXPECT_EQ(add(-1, -2), -3);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Особенности:

  • Поддержка смертельных тестов (death tests) для проверки assert.
  • Фабрика моков (gmock) для изоляции зависимостей.
  • Интеграция с CMake (find_package(GTest)).

2. Catch2

Современный фреймворк с выразительным синтаксисом. Не требует отдельной регистрации тестов — достаточно макроса TEST_CASE. Поддерживает BDD-стиль (Given-When-Then).

#include <catch2/catch_test_macros.hpp>

int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

TEST_CASE("Factorials are computed", "[math]") {
    REQUIRE(factorial(0) == 1);
    REQUIRE(factorial(1) == 1);
    REQUIRE(factorial(5) == 120);
}

TEST_CASE("Negative input", "[math][edge]") {
    REQUIRE_THROWS_AS(factorial(-1), std::domain_error);
}

Особенности:

  • Генерация тестовых данных (GENERATE).
  • Разделение тестов на секции (SECTION).
  • Автоматический выбор main() (если определить CATCH_CONFIG_MAIN).

3. doctest

Лёгкий и быстрый фреймворк, минимальное время компиляции. Идеален для проектов, где важна скорость сборки. Синтаксис похож на Catch2.

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>

int divide(int a, int b) {
    if (b == 0) throw std::invalid_argument("division by zero");
    return a / b;
}

TEST_CASE("Division") {
    CHECK(divide(10, 2) == 5);
    CHECK_THROWS_AS(divide(5, 0), std::invalid_argument);
}

Особенности:

  • Очень быстрая компиляция (заголовочный файл ~5 КБ).
  • Поддержка макросов CHECK, REQUIRE, WARN.
  • Встроенный репортёр в XML/JSON.

4. Boost.Test

Часть библиотек Boost. Имеет богатые возможности, но требует больше boilerplate-кода. Поддерживает автоматическую и ручную регистрацию тестов.

#define BOOST_TEST_MODULE MyTest
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(MathTests)

BOOST_AUTO_TEST_CASE(TestSum) {
    BOOST_CHECK_EQUAL(2 + 2, 4);
    BOOST_CHECK_CLOSE(3.14159, 3.14, 0.1); // точность 0.1%
}

BOOST_AUTO_TEST_CASE(TestFail) {
    BOOST_REQUIRE_MESSAGE(false, "This test always fails");
}

BOOST_AUTO_TEST_SUITE_END()

Особенности:

  • Широкий набор

Рекомендаций