首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将Boost.Test输出记录到HRF中的stdout和XML中的文件?

如何将Boost.Test输出记录到HRF中的stdout和XML中的文件?
EN

Stack Overflow用户
提问于 2014-10-22 10:17:15
回答 1查看 2.1K关注 0票数 2

我希望能够将Boost.Test输出记录到stdout/sterr和日志文件中。

但是,我也希望stdout日志以HumanReadableFormat格式显示,并且只有文件输出采用XML格式。

生成报告文件似乎是针对这里的。(官方文件)

选择格式可以在各种方式中完成,但似乎其中之一是被HRF或XML所困?

理由:

在或詹金斯服务器上运行测试时,xUnit插件 需要 日志 XML输出(相对于报表XML输出- log_level vs. report_level)。

但是,在服务器上运行测试、检测挂起的测试或快速手动检查测试当前的位置时,正在进行的日志输出(在HRF中)是非常有价值的。因此,我需要一个进行中的HRF日志来测试,最后我需要一个包含<TestLog>...</TestLog>输出的Boost.Test文件(而不是<TestResult>输出)。

请注意,我们通过Boost.Test运行单元测试和集成测试,因此其中一些测试的运行时间相当长。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-03 16:08:20

我已经做了:-)经过大量的尝试和错误之后,我设法找到了一种很好的方法,让Boost.Test框架本身来完成实际的输出工作,并且仍然将XML输出到一个文件中。

关键是要了解在Boost.Test中可以定制什么输出以及如何定制输出:

  • 有两个日志区域,测试日志和测试结果,只有测试日志是有用的,因为测试结果,即使在最高的细节级别也只是一个总结。
  • Boost.Test只支持一个输出流,因此它的替换不会立即起作用,尽管我们可以使用boost::iostreamtee_filter将其写入标准输出和文件。
  • 上面没有帮助,因为Boost.Test也只使用一个sinlge日志格式化程序(unit_test_log_formatter),所以即使您可以将输出分割成两个流,仍然存在一个问题,即您只能得到一种格式。
  • 但是,日志格式化程序可以通过boost::unit_test::unit_test_log.set_formatter设置,这正是我所要做的。

我为HRF格式化程序和XML格式化程序提供了一个薄包装,其中HRF格式化程序只记录到默认流,而XML格式化程序则写入自定义XML文件。

它似乎工作良好,但使用自己的风险,因为这是相当新的,并没有在所有的套件运行到现在。

代码语言:javascript
复制
#pragma once

// Copyright (c) 2014
// This file is distributed under the 
// Boost Software License - Version 1.0 - August 17th, 2003
// (See http://www.boost.org/LICENSE_1_0.txt )

#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/output/xml_log_formatter.hpp>
#include <fstream>

namespace boost { 
namespace unit_test { 
namespace output {

//! Log formatter for Boost.Test that outputs the logging output *both*
//! to the standard HRF formatter (normal output stream ~ cout) *and*
//! also to the XML formatter, but the XML is written to a report file.
//!
//! Usage: 
//! // Call in init_unit_test_suite: (this will override the --log_format parameter)
//! boost::unit_test::unit_test_log.set_formatter(
//!   new boost::unit_test::output::dual_log_formatter(L"filename.xml")
//! );
//!
//! Note: Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
//!       the HRF formatter used here.
//!
//! Note: Implemented in boost::unit_test::output for symmetry with existing formatter classes
//!
class dual_log_formatter : public unit_test_log_formatter {
public:
    // Formatter interface
    void log_start(std::ostream& os, counter_t test_cases_amount) override {
        hrf_logger.log_start(os, test_cases_amount);
        xml_logger.log_start(xml_file, test_cases_amount);
    }
    void log_finish(std::ostream& os) override {
        hrf_logger.log_finish(os);
        xml_logger.log_finish(xml_file);
    }
    void log_build_info(std::ostream& os) override {
        hrf_logger.log_build_info(os);
        xml_logger.log_build_info(xml_file);
    }

    void test_unit_start(std::ostream& os, test_unit const& tu) override {
        hrf_logger.test_unit_start(os, tu);
        xml_logger.test_unit_start(xml_file, tu);
    }

    void test_unit_finish(std::ostream& os, test_unit const& tu, unsigned long elapsed) override {
        hrf_logger.test_unit_finish(os, tu, elapsed);
        xml_logger.test_unit_finish(xml_file, tu, elapsed);
    }

    void test_unit_skipped(std::ostream& os, test_unit const& tu) override {
        hrf_logger.test_unit_skipped(os, tu);
        xml_logger.test_unit_skipped(xml_file, tu);
    }

    void log_exception(std::ostream& os, log_checkpoint_data const& checkpoint_data, execution_exception const& ex) override {
        hrf_logger.log_exception(os, checkpoint_data, ex);
        xml_logger.log_exception(xml_file, checkpoint_data, ex);
    }

    void log_entry_start(std::ostream& os, log_entry_data const& entry_data, log_entry_types let) override {
        hrf_logger.log_entry_start(os, entry_data, let);
        xml_logger.log_entry_start(xml_file, entry_data, let);
    }
    using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
    void log_entry_value(std::ostream& os, const_string value) override {
        hrf_logger.log_entry_value(os, value);
        xml_logger.log_entry_value(xml_file, value);
    }
    void log_entry_finish(std::ostream& os) override {
        hrf_logger.log_entry_finish(os);
        xml_logger.log_entry_finish(xml_file);
    }

    dual_log_formatter(const wchar_t* xmlFilename) { // Note: Use char* on non-MSVC compilers
        xml_file.open(xmlFilename);
    }

private:
    std::ofstream xml_file;
    compiler_log_formatter hrf_logger;
    xml_log_formatter xml_logger;
};

}
}
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26505229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档