文章目录
- [Catch2 开源库介绍与使用指南](#Catch2 开源库介绍与使用指南)
-
- [1. Catch2 简介](#1. Catch2 简介)
- [2. 安装 Catch2](#2. 安装 Catch2)
-
- 方法1:单头文件方式(推荐)
- 方法2:使用包管理器
- [方法3:CMake 集成](#方法3:CMake 集成)
- [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.hpp
和 catch_amalgamated.cpp
文件:
- 从 Catch2 GitHub 发布页 下载最新版本
- 将这两个文件添加到你的项目中
方法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. 最佳实践
- 为测试用例和章节使用描述性名称
- 使用标签组织测试(如
[core]
,[slow]
,[network]
) - 将测试代码与生产代码分开
- 保持测试独立,不依赖执行顺序
- 对性能测试使用
[!benchmark]
标签 - 使用
CAPTURE
宏在断言失败时显示变量值
Catch2 是一个功能强大但易于使用的测试框架,适合从小型项目到大型企业级应用的测试需求。它的设计哲学是"只需付出最少的努力就能获得最大的收益",使得编写和维护测试变得简单而愉快。