Catch2 开源库介绍与使用指南

文章目录

  • [Catch2 开源库介绍与使用指南](#Catch2 开源库介绍与使用指南)
    • [1. Catch2 简介](#1. Catch2 简介)
    • [2. 安装 Catch2](#2. 安装 Catch2)
    • [3. 基本用法](#3. 基本用法)
    • [4. 常用断言宏](#4. 常用断言宏)
    • [5. BDD 风格测试](#5. BDD 风格测试)
    • [6. 测试夹具(Test Fixtures)](#6. 测试夹具(Test Fixtures))
    • [7. 参数化测试](#7. 参数化测试)
    • [8. 运行测试](#8. 运行测试)
    • [9. 高级特性](#9. 高级特性)
    • [10. 与构建系统集成](#10. 与构建系统集成)
      • [与 CMake 集成](#与 CMake 集成)
    • [11. 最佳实践](#11. 最佳实践)

Catch2 开源库介绍与使用指南

1. Catch2 简介

Catch2 是一个现代的 C++ 测试框架,主要用于单元测试、集成测试和功能测试。它是原始 Catch 测试框架的进化版本,具有以下特点:

  • 简单易用:测试用例编写直观,学习曲线平缓
  • 无外部依赖:只需要包含一个头文件即可使用
  • 丰富的断言宏:提供多种断言方式
  • 测试发现机制:自动发现和运行测试用例
  • 良好的输出格式:测试结果清晰易读
  • 支持BDD风格:支持行为驱动开发(Behavior-Driven Development)风格测试

2. 安装 Catch2

方法1:单头文件方式(推荐)

最简单的使用方式是下载 catch_amalgamated.hppcatch_amalgamated.cpp 文件:

  1. Catch2 GitHub 发布页 下载最新版本
  2. 将这两个文件添加到你的项目中

方法2:使用包管理器

  • vcpkg : vcpkg install catch2
  • conan : conan install catch2/2.13.7@

方法3:CMake 集成

cmake 复制代码
# CMakeLists.txt
include(FetchContent)
FetchContent_Declare(
  Catch2
  GIT_REPOSITORY https://github.com/catchorg/Catch2.git
  GIT_TAG        v3.0.1
)
FetchContent_MakeAvailable(Catch2)

# 添加测试可执行文件
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

3. 基本用法

简单测试示例

cpp 复制代码
#define CATCH_CONFIG_MAIN  // 这行告诉Catch提供main() - 只在一个cpp文件中这样做
#include "catch.hpp"

unsigned int Factorial(unsigned int number) {
    return number <= 1 ? number : Factorial(number-1)*number;
}

TEST_CASE("Factorials are computed", "[factorial]") {
    REQUIRE(Factorial(1) == 1);
    REQUIRE(Factorial(2) == 2);
    REQUIRE(Factorial(3) == 6);
    REQUIRE(Factorial(10) == 3628800);
}

测试用例和章节

cpp 复制代码
TEST_CASE("Vector operations", "[vector]") {
    std::vector<int> v;
    
    SECTION("resizing bigger changes size and capacity") {
        v.resize(10);
        REQUIRE(v.size() == 10);
        REQUIRE(v.capacity() >= 10);
    }
    
    SECTION("resizing smaller changes size but not capacity") {
        v.resize(0);
        REQUIRE(v.size() == 0);
        REQUIRE(v.capacity() >= 10);
    }
}

4. 常用断言宏

Catch2 提供了多种断言宏:

  • REQUIRE(expr):表达式必须为真,否则停止当前测试用例
  • CHECK(expr):表达式应该为真,但即使失败也继续执行
  • REQUIRE_FALSE(expr):表达式必须为假
  • CHECK_FALSE(expr):表达式应该为假
  • REQUIRE_THROWS(expr):表达式必须抛出异常
  • CHECK_THROWS(expr):表达式应该抛出异常
  • REQUIRE_NOTHROW(expr):表达式不能抛出异常
  • CHECK_NOTHROW(expr):表达式不应该抛出异常

5. BDD 风格测试

Catch2 支持行为驱动开发(BDD)风格的测试:

cpp 复制代码
SCENARIO("Vectors can be sized and resized", "[vector]") {
    GIVEN("A vector with some items") {
        std::vector<int> v = {1, 2, 3};
        
        REQUIRE(v.size() == 3);
        REQUIRE(v.capacity() >= 3);
        
        WHEN("the size is increased") {
            v.resize(10);
            
            THEN("the size and capacity change") {
                REQUIRE(v.size() == 10);
                REQUIRE(v.capacity() >= 10);
            }
        }
    }
}

6. 测试夹具(Test Fixtures)

cpp 复制代码
class UniqueTestsFixture {
protected:
    UniqueTestsFixture() : unique_data(42) {}
    
    int unique_data; // 每个测试用例都有独立的副本
};

TEST_CASE_METHOD(UniqueTestsFixture, "Test with fixture", "[fixture]") {
    REQUIRE(unique_data == 42);
    unique_data++;
    REQUIRE(unique_data == 43);
}

TEST_CASE_METHOD(UniqueTestsFixture, "Another test with same fixture", "[fixture]") {
    // 这里的 unique_data 仍然是初始值 42
    REQUIRE(unique_data == 42);
}

7. 参数化测试

Catch2 支持参数化测试:

cpp 复制代码
TEST_CASE("Parameterized test", "[param]") {
    auto [input, expected] = GENERATE(
        std::make_tuple(1, 2),
        std::make_tuple(2, 4),
        std::make_tuple(3, 6)
    );
    
    CAPTURE(input); // 在失败时显示输入值
    REQUIRE(input * 2 == expected);
}

8. 运行测试

编译后直接运行测试程序:

复制代码
./tests  # 运行所有测试
./tests [factorial]  # 只运行标记为[factorial]的测试
./tests "Factorials*"  # 运行名称匹配"Factorials*"的测试

常用命令行选项:

  • -l, --list-tests:列出所有测试用例
  • -t, --list-tags:列出所有标签
  • -s, --success:显示成功的测试
  • -b, --break:在第一个失败时中断
  • -o, --out <filename>:将输出重定向到文件

9. 高级特性

基准测试

cpp 复制代码
TEST_CASE("Benchmark vector push_back", "[!benchmark]") {
    std::vector<int> v;
    
    BENCHMARK("Push back 100 elements") {
        for (int i = 0; i < 100; ++i) {
            v.push_back(i);
        }
    };
    REQUIRE(v.size() == 100);
}

自定义主函数

cpp 复制代码
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

int main(int argc, char* argv[]) {
    Catch::Session session;
    
    // 自定义配置
    int returnCode = session.applyCommandLine(argc, argv);
    if (returnCode != 0) return returnCode;
    
    // 在这里可以添加全局设置
    
    return session.run();
}

10. 与构建系统集成

与 CMake 集成

cmake 复制代码
enable_testing()

add_executable(tests 
    test1.cpp 
    test2.cpp
)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

add_test(NAME tests COMMAND tests)

11. 最佳实践

  1. 为测试用例和章节使用描述性名称
  2. 使用标签组织测试(如 [core], [slow], [network]
  3. 将测试代码与生产代码分开
  4. 保持测试独立,不依赖执行顺序
  5. 对性能测试使用 [!benchmark] 标签
  6. 使用 CAPTURE 宏在断言失败时显示变量值

Catch2 是一个功能强大但易于使用的测试框架,适合从小型项目到大型企业级应用的测试需求。它的设计哲学是"只需付出最少的努力就能获得最大的收益",使得编写和维护测试变得简单而愉快。

相关推荐
西北大程序猿几秒前
服务器代码知识点补充
服务器·开发语言·网络·c++·网络协议
yxc_inspire2 小时前
基于Qt的app开发第十四天
前端·c++·qt·app·面向对象·qss
Cai junhao3 小时前
【Qt】工具介绍和信号与槽机制
开发语言·c++·qt·qt6.3
byte轻骑兵11 小时前
【C++特殊工具与技术】优化内存分配(四):定位new表达式、类特定的new、delete表达式
开发语言·c++
广州正荣12 小时前
成绩管理革新者:C++驱动的智能数据处理平台
c++·人工智能·科技
90wunch12 小时前
对象回调初步研究
c++·windows·安全
Se_ren_di_pity12 小时前
C++ STL容器汇总
开发语言·c++
Wendy_robot12 小时前
【零基础勇闯嵌入式岗】从单片机低功耗中获得的启发
c++·单片机·嵌入式硬件
lul~15 小时前
[科研理论]无人机底层控制算法PID、LQR、MPC解析
c++·人工智能·无人机
我命由我1234517 小时前
STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式