资讯动态

TEN 框架内嵌 Catch2 的 CI 与工具链集成指南:reporter、Bazel、CMake 与调试脚本实战

发布时间:2026/9/28 20:51:17 来源:尧图企业网站定制
人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载导读Catch2 是 TEN-framework 源码树中经 clingo-sys 依赖引入的 C 单元测试框架其文档ci-and-misc.md系统讲解了它与 CI 构建服务器、Bazel 测试运行器、pkg-config、gdb/lldb 以及 CMake 生态的集成方式。本文以该文档为骨架结合仓库内 Catch2 3.8.0 的实际源码catch_config.cpp、reporter 实现reporters、CMake 脚本extras以及 clingo 测试目标libclingo/tests/CMakeLists.txt展开深度讲解。读完本文你将掌握在 CI 中选用 reporter 输出测试结果、让 Catch2 原生适配 Bazel 的分片与过滤、通过 CMake 自动注册测试用例以及用调试脚本跳过框架内部代码等一整套实战能力。Continuous Integration 系统用 reporter 对接构建服务器Catch2 自带多款 reporter覆盖了绝大多数构建服务器的输出格式需求。文档指出这些 reporter 中 XML 与 JUnit 两个是内建的TeamCity 以独立头文件提供此外还提供 Automake、TAP 与 SonarQube reporter。在仓库源码中可以看到这些 reporter 均以独立翻译单元实现于 src/catch2/reporters 目录catch_reporter_junit.cpp、catch_reporter_teamcity.cpp、catch_reporter_automake.cpp、catch_reporter_tap.cpp、catch_reporter_sonarqube.cpp等可通过命令行-r name或--reporter name选用。XML Reporter-r xmlXML reporter 输出的是 Catch 专属的 XML 格式。它的优势在于与 Catch 的执行模型高度契合——尤其是嵌套 section 这类比较特殊的功能——并且是完全流式的边跑边写无需等全部结果累积完毕才开始输出。缺点是这种格式是 Catch 特有的现有构建服务器无法原生识别通常需要配合 XSLT 变换例如转成 HTML才能消费而一旦经过变换流式优势也就随之失去了。JUnit Reporter-r junitJUnit reporter 输出模仿 JUnit ANT schema 的 XML。绝大多数构建服务器都能直接消费 JUnit Ant schema因此通常无需额外处理即可接入。其劣势在于该 schema 是围绕 JUnit 的工作方式设计的与 Catch 的运行模型存在显著错位同时该格式不可流式——因为开头的元素要承载失败/通过测试的计数属性必须等整个测试运行结束才能写出。这一点在 catch_config.cpp 的 Bazel 环境读取逻辑中也有体现JUnit 输出文件是在测试结束后一次性落盘的。TeamCity Reporter-r teamcityTeamCity reporter 向 stdout 输出 TeamCity 服务消息使用前需要额外包含一个头文件。它是与 TeamCity 配合的最佳选择但完全不适用于其他场景。格式是流式的边跑边写不过测试结果要等整个 suite通常是整个测试运行完成后才会出现在 TeamCity 界面中。Automake Reporter-r automakeAutomake reporter 输出 automake 通过make check预期的 meta tags便于在 automake 驱动的构建流程中直接采集测试结果。TAP Reporter-r tapTAPTest Anything Protocolreporter 输出 TAP 协议格式。由于 Catch 测试套件是增量的、且支持运行指定测试其 TAP 实现会在最后才写出 suite 中的测试总数。SonarQube Reporter-r sonarqubeSonarQube reporter 输出 SonarQube Generic Test Data 的 XML 格式用于向 SonarQube 上报测试指标测试用例、失败、耗时等供质量门禁分析使用。Bazel 测试运行器集成环境变量驱动的原生适配Catch2 理解 Bazel 用于控制测试执行的环境变量仓库源码 catch_config.cpp 给出了完整的实现证据环境变量作用XML_OUTPUT_FILE指定 JUnit 输出路径Catch2 会自动注册一个输出到该文件的 JUnit reporterTESTBRIDGE_TEST_ONLY测试过滤等价于在命令行传入测试 specTEST_SHARD_INDEX测试分片的索引TEST_TOTAL_SHARDS测试分片总数TEST_SHARD_STATUS_FILE分片状态文件路径BAZEL_TEST设为1时启用 Bazel 环境变量支持集成开关通过编译期配置选项见configuration.md中的 Bazel support或设置BAZEL_TEST1环境变量来启用。源码中enableBazelEnvSupport()的逻辑是若定义了CATCH_CONFIG_BAZEL_SUPPORT宏则恒为开启否则检查环境变量BAZEL_TEST是否存在catch_config.cpp。从源码可以看到三个关键实现细节JUnit 输出接管readBazelEnvVars()读取XML_OUTPUT_FILE后会向 reporter 规格列表追加{ junit, 该路径, {}, {} }catch_config.cpp。注释说明Bazel 通过该环境变量给出 XML 输出路径若测试期间写入此文件Bazel 便不会生成默认的 XML 输出从而让输出文件承载更高级别的细节信息。过滤覆盖 CLITESTBRIDGE_TEST_ONLY存在时会先清空命令行传入的测试 spec 再写入环境变量的值即环境变量优先catch_config.cpp。分片三件套必须齐全readBazelShardingOptions()要求TEST_SHARD_INDEX、TEST_TOTAL_SHARDS、TEST_SHARD_STATUS_FILE三者同时存在才启用分片缺失任一变量都会向 stderr 打印Warning: Bazel shard configuration is missing var. Shard configuration is skipped.并跳过分片配置catch_config.cpp。三个变量都齐备时Catch2 会以 truncate 模式打开状态文件保证写入成功随后将 shardIndex 与 shardCount 写入配置catch_config.cpp。版本信息方面XML_OUTPUT_FILE支持在 Catch2 3.0.1 引入TESTBRIDGE_TEST_ONLY与分片支持在 3.2.0 引入BAZEL_TEST在 3.1.0 引入本仓库内嵌版本为 3.8.0见 catch/CMakeLists.txt以上能力全部可用。Low-level 工具覆盖率、pkg-config 与调试器脚本CodeCoverageGCOV、LCOV...若使用 GCOV 获取测试覆盖率并希望与 CMake、Catch 集成官方文档建议参考外部示例工程catch_cmake_coverage文中给出了其仓库地址核心思路通常是用--coverage编译选项生成.gcno/.gcda数据后交给 LCOV 汇总。pkg-configCatch2 以名称catch2注册了基础的 pkg-config 集成。安装完成后即可用pkg-config --cflags catch2取得头文件包含路径便于在非 CMake 的构建脚本中引用。gdb 与 lldb 脚本Catch2 的extras目录内附带了两个调试脚本gdbinit用于 gdb、lldbinit用于 lldb。在仓库中实际存在extras/gdbinit 与 extras/lldbinit。加载进对应调试器后单步调试代码时会自动跳过 Catch2 内部实现直接停留在被测代码上显著提升调试体验。CMake 集成从 target 到自动测试注册Catch2 的 CMake 集成文档已独立成页cmake-integration.md此处先给出与 CI/工具链相关的核心结论再结合本仓库的实际用法展开。消费侧Catch2::Catch2与Catch2::Catch2WithMainCatch2 的 CMake 构建导出两个命名空间 targetCatch2::Catch2和Catch2::Catch2WithMain。不需要自定义main时应当链接Catch2::Catch2WithMain——它会把 Catch2 及其 main 实现这两个静态库一并链接并配好 include 路径需要自定义main时只链接Catch2::Catch2。典型用法find_package(Catch2 3 REQUIRED) # 使用 Catch2 自带的 main add_executable(tests test.cpp) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) # 需要自定义 main 的测试 add_executable(custom-main-tests test.cpp test-main.cpp) target_link_libraries(custom-main-tests PRIVATE Catch2::Catch2)这两个 target 在 Catch2 以子目录形式引入时同样可用——把find_package换成add_subdirectory(lib/Catch2)即可也可以用FetchContent拉取源码后调用FetchContent_MakeAvailable(Catch2)。在本仓库中clingo 的测试工程正是这样消费的CLINGO_BUILD_TESTS开启后若CLINGO_USE_LOCAL_CATCH为真则add_subdirectory(catch)直接内嵌构建否则find_package(Catch2 3.1 REQUIRED)见 third_party/CMakeLists.txt。三个测试目标都链接了Catch2::Catch2WithMain例如add_executable(test_clingo ${source}) target_link_libraries(test_clingo PRIVATE libclingo Catch2::Catch2WithMain) add_test(NAME test_clingo COMMAND test_clingo)见 libclingo/tests/CMakeLists.txtlibgringo、libreify的测试目录结构相同。自动测试注册catch_discover_testsextras/Catch.cmake提供catch_discover_tests函数运行目标可执行文件并传--list-test标志解析输出得到全部测试再为每个 TEST_CASE 在 CTest 中注册独立测试。其配套脚本CatchAddTests.cmake负责实际的发现与注册逻辑均在 extras 目录下。最小用法cmake_minimum_required(VERSION 3.16) project(baz LANGUAGES CXX VERSION 0.0.1) find_package(Catch2 REQUIRED) add_executable(tests test.cpp) target_link_libraries(tests PRIVATE Catch2::Catch2) include(CTest) include(Catch) catch_discover_tests(tests)使用FetchContent时include(Catch)需要显式把 extras 目录加入模块路径list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) include(CTest) include(Catch) catch_discover_tests(tests)catch_discover_tests支持丰富的定制参数参数说明TEST_SPEC arg1...配合--list-test-names-only传入的测试用例/通配/tag/tag 表达式过滤EXTRA_ARGS arg1...附加到每个测试用例命令行的额外参数WORKING_DIRECTORY dir运行测试用例的工作目录缺省为当前二进制目录TEST_PREFIX prefix给每个发现的测试名加前缀便于同一可执行文件多次调用时区分TEST_SUFFIX suffix同上加后缀可与前缀同时使用PROPERTIES name1 value1...为本次发现的全部测试设置额外 CTest 属性TEST_LIST var把测试列表存入变量var默认target_TESTS仅 CTest 内可见REPORTER reporter运行测试时以--reporter reporter传入指定 reporterOUTPUT_DIR dir以--out dir/test_name传参应优先用它而非EXTRA_ARGS --out foo避免并行执行时写结果文件的竞态OUTPUT_PREFIX prefix配合OUTPUT_DIR使用输出文件名变为dir/prefixtest_nameOUTPUT_SUFFIX suffix配合OUTPUT_DIR使用输出文件名变为dir/test_namesuffix可用来加.xml扩展名DISCOVERY_MODE POST_BUILD|PRE_TEST默认POST_BUILD在构建时发现PRE_TEST延迟到测试执行前适用于交叉编译环境。未传时取全局变量CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE的值SKIP_IS_FAILURE被跳过的测试标记为失败ADD_TAGS_AS_LABELS把测试的 tag 作为 label 加到 CTest已废弃的ParseAndAddCatchTests.cmake该脚本从 Catch2 2.13.4 起被标记废弃由catch_discover_tests取代。它通过解析目标关联的所有实现文件来注册测试而非运行可执行文件存在明显局限被注释掉的测试也会被注册且只能识别 Catch 断言宏的子集遇到无法解析的宏的测试会被静默忽略。其定制点包括PARSE_CATCH_TESTS_VERBOSEON时打印调试消息默认OFFPARSE_CATCH_TESTS_NO_HIDDEN_TESTSON时不注册隐藏测试[.]或[.foo]标记默认OFFPARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAMEON时在 CTest 测试名中加入 fixture 类名默认ONPARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAMEON时在测试名中加入 target 名默认ONPARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDSON时把测试文件加入CMAKE_CONFIGURE_DEPENDS测试文件变化即重新配置 CMake 以自动发现新测试默认OFF。另外可在调用前设置OptionalCatchTestLauncher指定启动命令例如用 MPI 运行部分测试set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC}) ParseAndAddCatchTests(mpi_foo) unset(OptionalCatchTestLauncher) ParseAndAddCatchTests(bar)分片注册CatchShardTests.cmakeCatchShardTests.cmakeCatch2 3.1.0 引入提供catch_add_sharded_tests(TEST_BINARY)把目标的测试随机分片且每次 CTest 运行都会更换随机种子。当前支持三个定制点SHARD_COUNT分片数、REPORTER测试用的 reporter spec、TEST_SPEC过滤测试用的 spec。示例include(CatchShardTests) catch_add_sharded_tests(foo-tests SHARD_COUNT 4 REPORTER xml::out- TEST_SPEC A ) catch_add_sharded_tests(tests SHARD_COUNT 8 REPORTER xml::out- TEST_SPEC B )上面会注册 12 个 CTest 测试4 8 个分片分别从foo-tests与tests两个测试二进制按 spec 过滤后运行。注意文档明确说明该脚本目前是每次 CTest 运行重新播种分片的概念验证实现尚不支持也不计划支持catch_discover_tests的全部定制点。项目级 CMake 选项消费 Catch2 的项目可用的选项包括BUILD_TESTINGON且 Catch2 非子项目时构建测试二进制默认ONCATCH_INSTALL_DOCS安装时包含文档默认ONCATCH_INSTALL_EXTRAS安装时包含 extras 目录上述 CMake 脚本与调试器辅助文件默认ONCATCH_DEVELOPMENT_BUILD以开发模式配置构建启用测试工程、告警等默认OFF。开启CATCH_DEVELOPMENT_BUILD后还有更多选项CATCH_BUILD_TESTING构建 SelfTest默认ON需与BUILD_TESTING同时为ON、CATCH_BUILD_EXAMPLES默认OFF、CATCH_BUILD_EXTRA_TESTS默认OFF、CATCH_BUILD_FUZZERS默认OFF、CATCH_ENABLE_WERROR编译加-Werror默认ON、CATCH_BUILD_SURROGATES逐个单独编译每个头文件以验证其自足性默认OFF。CATCH_CONFIG_*的 CMake 开关自 Catch2 3.0.1 起configuration.md中记载的编译期配置选项都可以通过 CMake 设置定义某选项为ON即启用例如-DCATCH_CONFIG_NOSTDOUTON。需要注意设为OFF并不会关闭该选项要强制关闭必须把对应的_NO_形式设为ON例如-DCATCH_CONFIG_NO_COLOUR_WIN32ON。以CATCH_CONFIG_COLOUR_WIN32为例的行为矩阵-DCATCH_CONFIG_COLOUR_WIN32-DCATCH_CONFIG_NO_COLOUR_WIN32结果ONONerror矛盾配置报错ONOFFforce-onOFFONforce-offOFFOFFauto-detect安装 Catch2git 仓库、vcpkg 与 Bazel从 git 仓库安装当系统包管理器提供的版本过旧时文档举例 Ubuntu 16.04 仅有 1.2.0可从源码安装$ git clone https://github.com/catchorg/Catch2.git $ cd Catch2 $ cmake -B build -S . -DBUILD_TESTINGOFF $ sudo cmake --build build/ --target install无超级用户权限时需要额外指定CMAKE_INSTALL_PREFIX并在随后调用find_package时按该前缀调整查找路径。从 vcpkg 安装也可用 vcpkg 依赖管理器构建安装git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install ./vcpkg install catch2从 Bazel Central Registry 使用Catch2 是 Bazel Central Registry 的受支持模块在MODULE.bazel中加一行依赖声明最新受支持版本见 registry 页面随后在每个 C 测试规则中加入catch2_main依赖cc_test( name example_test, srcs [example_test.cpp], deps [ :example, catch2//:catch2_main, ], )结合本仓库的落地路径TEN-framework 仓库中Catch2 位于third_party/clingo-sys/clingo/third_party/catch版本为 3.8.0CMakeLists.txt被 clingo 的libclingo、libgringo、libreify三个测试目标共同使用。若你希望在本仓库的 C 测试工程中落地上述 CI 能力可以按以下路径操作选用 reporter在运行测试二进制时追加-r junit -o junit.xml或--reporter junit --out junit.xml输出 JUnit 格式供 Jenkins、GitLab CI 等消费需要流式输出时改用-r xml。接入 Bazel在 Bazel 测试环境中设置BAZEL_TEST1并让 Bazel 注入XML_OUTPUT_FILE、TESTBRIDGE_TEST_ONLY、TEST_SHARD_INDEX/TEST_TOTAL_SHARDS/TEST_SHARD_STATUS_FILECatch2 即自动完成 JUnit 输出、过滤与分片catch_config.cpp。CTest 注册仿照 libclingo/tests/CMakeLists.txt 链接Catch2::Catch2WithMain并引入 extras/Catch.cmake 调用catch_discover_tests实现细粒度测试注册。调试在 gdb/lldb 中加载 extras/gdbinit 与 extras/lldbinit单步时自动跳过 Catch2 内部。以上能力均以当前仓库内嵌的 Catch2 3.8.0 源码为准各 reporter 的实现文件、Bazel 环境变量解析逻辑与 CMake 辅助脚本均可直接在 catch 目录下查阅验证。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐Catch2 单元测试框架实战入门TEN-framework 内置 Catch2 的 TEST_CASE、Sections 与 BDD 指南Catch2 单元测试框架实战入门TEN framework 内置 Catch2 的 TEST_CASE、Sections 与 BDD 指南 Catch2 是人工智能AI Agent多模态语音AI 应用TEN-framework 仓库内嵌的 Catch2C 单元测试与微基准测试实战指南TEN framework 仓库内嵌的 Catch2C 单元测试与微基准测试实战指南 本篇指南以 third_party/clingo sys/cling人工智能AI Agent多模态语音AI 应用POCO内存泄漏检测工具集成CMake与测试框架POCO内存泄漏检测工具集成CMake与测试框架 你还在为内存泄漏头疼一文解决POCO开发痛点 内存泄漏Memory Leak是C开发中常见的隐患后端网络/通信数据库密码学Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑