如何将Boost.Test输出记录到HRF中的stdout和XML中的文件中
How to log Boost.Test output to both stdout in HRF and to a file in XML?
我想启用Boost的日志记录。测试输出到stdout/ster和日志文件。
但是,我也希望stdout日志记录采用HumanReadableFormat,并且只有文件输出采用XML格式。
生成报告文件的问题似乎就在这里。(官方文件)
可以通过各种方式选择格式,但似乎只能使用HRF或XML?
理由:
在或Jenkins服务器上运行测试时,xUnit插件需要日志XML输出(而不是报告XML输出——log_level
与report_level
)。
但是,当测试在服务器上运行时,正在进行的日志输出(在HRF中)非常有价值,用于检测挂起的测试或快速手动检查测试当前的位置。因此,我想要一个正在进行的测试的HRF日志,最后我需要一个包含Boost.Test的<TestLog>...</TestLog>
输出(而不是<TestResult>
输出)的XML文件。
请注意,我们通过Boost.Test运行单元测试和集成测试,因此其中一些测试是长时间运行的。
我已经做到了:-)经过大量的尝试和错误,我设法找到了一种让Boost.Test框架本身完成实际输出工作的好方法,并且仍然将XML输出到一个文件中。
关键是要了解什么以及如何在Boost中自定义输出。测试:
- 有两个日志区域,测试日志和测试结果,只有测试日志是有用的,因为测试结果,即使在最高详细级别,也只是摘要
- Boost.Test只支持一个单个输出流进行输出,因此替换它并不能立即起到帮助作用,尽管可以使用
boost::iostream
和tee_filter
同时写入stdout和文件 - 上面没有帮助,因为Boost.Test也只使用一个sinlge日志格式化程序(
unit_test_log_formatter
),所以即使您可以将输出拆分为两个流,您仍然会遇到只有一个格式的问题 - 然而,日志格式化程序可以通过
boost::unit_test::unit_test_log.set_formatter
设置,这正是我正在做的
我在HRF格式化程序和XML格式化程序上提供了一个瘦包装器,其中HRF格式化器只记录到默认流,XML格式化程序写入到自定义XML文件。
它似乎工作得很好,但使用风险自负,因为这是一个非常新的功能,还没有在所有套件上运行。
#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;
};
}
}
}
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 将字符串存储在c++中的稳定内存中
- 文本文件中的单词链表
- 递归函数计算序列中的平方和(并输出过程)
- 如何从C++中的依赖类型中获得它所依赖的类型
- C++中的"inline"关键字
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- 如何将控制台(stdout)添加为g3log中的接收器
- 如何将缓冲区打印到C 中的Stdout
- 连接到子进程stdout的管道中的消息不完整
- 如何将Boost.Test输出记录到HRF中的stdout和XML中的文件中
- 将stdout和stderr重定向到c++中的文件
- 我如何知道C++中stdout指向的位置