Какие библиотеки для тестирования вы использовали в проектах на C++?

Ответ

В C++ проектах я в основном работал со следующими библиотеками для модульного тестирования:

  • Google Test (gtest) с Google Mock (gmock): Это мой основной выбор для больших проектов. Фреймворк предоставляет богатый набор макросов для утверждений (ASSERT_*, EXPECT_*), поддержку фикстур, параметризованных тестов и мощную систему мок-объектов.

    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    
    TEST(CalculatorTest, AddsTwoNumbers) {
        EXPECT_EQ(Add(2, 3), 5);
    }
    
    class MockDatabase : public DatabaseInterface {
    public:
        MOCK_METHOD(std::string, FetchName, (int id), (override));
    };
    
    TEST(UserTest, GetsUserName) {
        MockDatabase db;
        EXPECT_CALL(db, FetchName(42))
            .WillOnce(Return("John Doe"));
        // Тестируемый код, использующий db
    }
  • Catch2: Отличный современный header-only фреймворк. Я использовал его в небольших проектах или библиотеках из-за простоты интеграции (просто добавить один заголовочный файл) и читаемого синтаксиса BDD-стиля.

    #define CATCH_CONFIG_MAIN
    #include <catch2/catch_all.hpp>
    
    TEST_CASE("Vector can be sized and resized", "[vector]") {
        std::vector<int> v(5);
        REQUIRE(v.size() == 5);
        REQUIRE(v.capacity() >= 5);
    
        SECTION("resizing bigger changes size and capacity") {
            v.resize(10);
            REQUIRE(v.size() == 10);
            REQUIRE(v.capacity() >= 10);
        }
    }

Для создания тестовых дублей (mocks/stubs) в проектах без gmock я иногда применял FakeIt или Trompeloeil (для C++14/17). Для интеграционного и системного тестирования часто писал собственные утилиты на основе Boost.Test или использовал скрипты на Python.

Ответ 18+ 🔞

Да ты посмотри, какие у нас тут библиотеки для тестов подъехали — прямо как на параде, блядь! Овердохуища вариантов, глаза разбегаются, ёпта.

Ну, первым делом, конечно, Google Test с Google Mock. Это, можно сказать, мой конёк, когда проект размером с хороший такой особняк. Чувак, там столько всего наворочено — макросы для проверок, фикстуры, тесты с параметрами... А уж моки — это вообще отдельная песня, ядрёна вошь! Прям как по маслу: объявил интерфейс, наклепал мок-класс, прописал ожидания — и сиди, проверяй, как твой код с этим виртуальным говном взаимодействует. Удобно, блядь, до безобразия.

#include <gtest/gtest.h>
#include <gmock/gmock.h>

TEST(CalculatorTest, AddsTwoNumbers) {
    EXPECT_EQ(Add(2, 3), 5);
}

class MockDatabase : public DatabaseInterface {
public:
    MOCK_METHOD(std::string, FetchName, (int id), (override));
};

TEST(UserTest, GetsUserName) {
    MockDatabase db;
    EXPECT_CALL(db, FetchName(42))
        .WillOnce(Return("John Doe"));
    // Тестируемый код, использующий db
}

А вот Catch2 — это уже другая история, более камерная. Header-only, понимаешь? Захотел — взял один файлик, кинул в проект, и всё, можешь тесты писать. Никакой лишней возни с линковкой, ебушки-воробушки! И синтаксис у него такой... как бы сказать... человеческий. BDD-стиль, где SECTION внутри TEST_CASE — смотрится чисто и понятно, не то что эти древние монстры.

#define CATCH_CONFIG_MAIN
#include <catch2/catch_all.hpp>

TEST_CASE("Vector can be sized and resized", "[vector]") {
    std::vector<int> v(5);
    REQUIRE(v.size() == 5);
    REQUIRE(v.capacity() >= 5);

    SECTION("resizing bigger changes size and capacity") {
        v.resize(10);
        REQUIRE(v.size() == 10);
        REQUIRE(v.capacity() >= 10);
    }
}

Ну а если вдруг проект без gmock, но моки нужны — тут уже в ход идут другие инструменты. FakeIt или Trompeloeil (для свежих стандартов) — тоже ребята ничего, справляются. А для тестов интеграционных, где всё вместе склепать надо, часто приходилось либо на Boost.Test опираться, либо свои костыли на Python пилить. В общем, скучать не приходится, работа кипит, блядь!