跳转至

Catch2 基本测试用例

Catch2 是一个现代 C++ 单元测试框架,支持 TEST_CASESECTION、BDD 风格等。

项目地址:Catch2

0. 配置方法

1. 源代码文件 test.cpp

#define CATCH_CONFIG_MAIN
#include "catch_amalgamated.hpp"

2. 编译命令

g++ test.cpp catch_amalgamated.cpp -std=c++17 -o test
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.5.2
)

然后:

#include <catch2/catch_test_macros.hpp>

1. 最简单的测试

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

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

TEST_CASE("加法函数测试", "[math]")
{
    REQUIRE(add(1, 2) == 3);
    REQUIRE(add(-1, 1) == 0);
}
  • TEST_CASE 定义测试用例
  • REQUIRE 断言失败后立即终止当前测试
  • [math] 是 tag,可用于过滤测试

2. CHECK 与 REQUIRE 的区别

#include <catch2/catch_test_macros.hpp>

TEST_CASE("CHECK 示例")
{
    CHECK(1 + 1 == 2);
    CHECK(2 * 2 == 4);

    // 即使失败,也继续执行后面的检查
    CHECK(2 - 1 == 0);

    CHECK(10 / 2 == 5);
}

区别:

失败后
REQUIRE 立即停止当前测试
CHECK 继续执行

3. 使用 SECTION

适合复用初始化代码。

#include <catch2/catch_test_macros.hpp>
#include <vector>

TEST_CASE("vector 测试")
{
    std::vector<int> vec = {1, 2, 3};

    SECTION("size 检查")
    {
        REQUIRE(vec.size() == 3);
    }

    SECTION("push_back 检查")
    {
        vec.push_back(4);

        REQUIRE(vec.size() == 4);
        REQUIRE(vec.back() == 4);
    }

    SECTION("clear 检查")
    {
        vec.clear();

        REQUIRE(vec.empty());
    }
}

SECTION 会分别运行,每次都会重新初始化 vec。 (Stack Overflow1)

4. 异常测试

#include <catch2/catch_test_macros.hpp>
#include <stdexcept>

int divide(int a, int b)
{
    if (b == 0)
        throw std::runtime_error("divide by zero");

    return a / b;
}

TEST_CASE("异常测试")
{
    REQUIRE(divide(10, 2) == 5);

    REQUIRE_THROWS(divide(10, 0));

    REQUIRE_THROWS_AS(
        divide(10, 0),
        std::runtime_error
    );
}

常用宏:

作用
REQUIRE_THROWS 要求抛异常
REQUIRE_THROWS_AS 要求抛指定类型异常
REQUIRE_NOTHROW 不允许异常

5. 字符串测试

#include <catch2/catch_test_macros.hpp>
#include <string>

TEST_CASE("字符串测试")
{
    std::string s = "hello";

    REQUIRE(s.size() == 5);

    CHECK(s == "hello");

    CHECK_FALSE(s.empty());
}

6. BDD 风格测试

Catch2 支持 Given/When/Then 风格。 (Builder.io2)

#include <catch2/catch_test_macros.hpp>
#include <vector>

SCENARIO("vector 可以动态扩容")
{
    GIVEN("一个包含 3 个元素的 vector")
    {
        std::vector<int> v = {1, 2, 3};

        WHEN("插入一个新元素")
        {
            v.push_back(4);

            THEN("size 应该变为 4")
            {
                REQUIRE(v.size() == 4);
            }

            THEN("最后一个元素应该是 4")
            {
                REQUIRE(v.back() == 4);
            }
        }
    }
}

7. 参数化模板测试

适合泛型代码。 (DeepWiki3)

#include <catch2/catch_template_test_macros.hpp>

template<typename T>
T square(T x)
{
    return x * x;
}

TEMPLATE_TEST_CASE(
    "square 测试",
    "[template]",
    int,
    float,
    double)
{
    REQUIRE(square(TestType(3)) == TestType(9));
}

8. 运行测试

编译:

g++ test.cpp -std=c++17

运行:

./a.out

按 tag 运行:

./a.out [math]

只运行某个测试:

./a.out "加法函数测试"

Catch2 支持通过名字和 tag 过滤测试。 (DeepWiki4)