You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:20:33