Skip to content

Catch2 — 测试框架

Catch2 是 C++ 现代测试框架,BDD 风格,单头文件,断言语法自然,是 GoogleTest 的流行替代。

安装

bash
vcpkg install catch2

# CMake
find_package(Catch2 REQUIRED)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

基本测试

cpp
#include <catch2/catch_test_macros.hpp>

TEST_CASE("向量基本操作", "[vector]") {
    std::vector<int> v = {1, 2, 3};

    REQUIRE(v.size() == 3);  // 失败则停止
    CHECK(v[0] == 1);        // 失败继续
    CHECK(v.back() == 3);

    SECTION("添加元素") {
        v.push_back(4);
        REQUIRE(v.size() == 4);
        CHECK(v.back() == 4);
    }

    SECTION("删除元素") {
        v.pop_back();
        REQUIRE(v.size() == 2);
    }
}

// BDD 风格
SCENARIO("用户登录", "[auth]") {
    GIVEN("一个已注册用户") {
        User user{"alice", "password123"};

        WHEN("使用正确密码登录") {
            auto result = login(user.name, "password123");
            THEN("登录成功") {
                REQUIRE(result.success);
                REQUIRE_FALSE(result.token.empty());
            }
        }

        WHEN("使用错误密码登录") {
            auto result = login(user.name, "wrong");
            THEN("登录失败") {
                REQUIRE_FALSE(result.success);
            }
        }
    }
}

参数化测试

cpp
#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators.hpp>

TEST_CASE("素数检测", "[math]") {
    auto n = GENERATE(2, 3, 5, 7, 11, 13, 17, 19, 23);
    REQUIRE(is_prime(n));
}

TEST_CASE("非素数", "[math]") {
    auto n = GENERATE(1, 4, 6, 8, 9, 10, 12);
    REQUIRE_FALSE(is_prime(n));
}

// 范围生成器
TEST_CASE("范围测试") {
    auto i = GENERATE(range(1, 10));
    REQUIRE(i > 0);
    REQUIRE(i < 10);
}

异常与浮点

cpp
TEST_CASE("异常测试") {
    REQUIRE_THROWS(risky_function());
    REQUIRE_THROWS_AS(parse_int("abc"), std::invalid_argument);
    REQUIRE_NOTHROW(safe_function());
}

TEST_CASE("浮点比较") {
    using Catch::Approx;
    REQUIRE(3.14 == Approx(3.14159).epsilon(0.01));
    REQUIRE(1.0 / 3.0 == Approx(0.333).margin(0.001));
}

关键认知

Catch2 的 SECTION 机制让每个 section 都从 TEST_CASE 开头重新执行,保证测试独立性。GENERATE 实现参数化测试,比 GoogleTest 的参数化更简洁。Approx 处理浮点比较,避免精度问题。

系统学习 C++ 生态,深入底层架构