如何为Catch2单头文件版本(v2)创建自定义报告器?
Catch2 v2单头文件版本自定义报告器解决方案
关于默认报告器工作的疑惑
默认报告器能正常运行,是因为它们的实现属于Catch2内部代码的一部分——单头文件版本在编译时会自动包含这些默认报告器的实现(位于CATCH_CONFIG_IMPL激活的内部分支中)。而用户的代码处于外部编译上下文,不会触发该分支,因此无法看到基类,但默认报告器已经提前完成注册,所以可以直接调用。
自定义报告器的两种实现方法
方法一:暴露基类并继承简化实现
Catch2 v2单头版中,StreamingReporterBase和CumulativeReporterBase默认被隐藏在预编译分支后,只需在包含Catch头文件之前定义CATCH_CONFIG_ENABLE_REPORTER_BASES宏,就能解锁这些基类的访问权限,之后即可按照官方文档的方式继承实现:
#define CATCH_CONFIG_ENABLE_REPORTER_BASES #define CATCH_CONFIG_RUNNER #include "catch.hpp" class MyCustomReporter : public Catch::StreamingReporterBase { public: using StreamingReporterBase::StreamingReporterBase; // 实现你需要的回调方法 void testCaseStarting(const Catch::TestCaseInfo& info) override { stream() << "开始测试用例: " << info.name << "\n"; } void testCaseEnded(const Catch::TestCaseStats& stats) override { stream() << "结束测试用例: " << stats.testInfo.name << " (通过断言数: " << stats.totals.assertions.passed << ")\n"; } }; // 注册自定义报告器 CATCH_REGISTER_REPORTER("custom", MyCustomReporter) int main(int argc, char* argv[]) { return Catch::Session().run(argc, argv); }
方法二:直接实现底层Reporter接口
如果上述宏在你的版本中不生效,可以直接实现最底层的Catch::Reporter纯虚接口。这种方式需要实现更多方法,但兼容性更强:
#define CATCH_CONFIG_RUNNER #include "catch.hpp" class MyCustomReporter : public Catch::Reporter { public: explicit MyCustomReporter(Catch::ReporterConfig const& config) : m_config(config) {} std::string getDescription() const override { return "自定义测试报告器"; } void testRunStarting(Catch::TestRunInfo const& info) override { m_config.stream() << "测试运行开始: " << info.name << "\n"; } void testCaseStarting(Catch::TestCaseInfo const& info) override { m_config.stream() << "开始测试用例: " << info.name << "\n"; } void assertionStarting(Catch::AssertionInfo const&) override {} bool assertionEnded(Catch::AssertionStats const& stats) override { if(stats.assertionResult.getResultType() == Catch::ResultWas::Failed) { m_config.stream() << "断言失败: " << stats.assertionResult.getExpression() << "\n"; } return true; } void testCaseEnded(Catch::TestCaseStats const& stats) override { m_config.stream() << "测试用例结束: " << stats.testInfo.name << " (通过: " << stats.totals.assertions.passed << ", 失败: " << stats.totals.assertions.failed << ")\n"; } void testRunEnded(Catch::TestRunStats const& stats) override { m_config.stream() << "测试运行结束. 总通过断言数: " << stats.totals.assertions.passed << ", 失败: " << stats.totals.assertions.failed << "\n"; } private: Catch::ReporterConfig m_config; }; CATCH_REGISTER_REPORTER("custom", MyCustomReporter) int main(int argc, char* argv[]) { return Catch::Session().run(argc, argv); }
使用方式
编译代码后,运行测试程序时加上--reporter custom参数,即可启用你的自定义报告器。
内容的提问来源于stack exchange,提问作者Mickaël C. Guimarães
相关产品推荐
相关产品推荐

