Я хотел бы включить запись выходных данных Boost.Test в и то и другое стандартный вывод / стерр и в лог-файл.
Тем не менее, я также хотел бы, чтобы ведение журнала stdout было в HumanReadableFormat, и только вывод файла был в формате XML.
Создание файла отчета, похоже, решено Вот. (официальные документы)
Выбор формата можно сделать в Различные пути, но кажется, что кто-то застрял с HRF или XML?
Обоснование:
При запуске тестов на или Дженкинс сервер, плагин xUnit требует журнал XML-вывод (в отличие от доклад Вывод XML — log_level
против report_level
).
Тем не менее, текущие выходные данные журнала (в HRF) очень ценны в то время как тесты выполняются на сервере, чтобы обнаружить зависшие тесты или выполнить быструю ручную проверку того, где тесты находятся в данный момент. Поэтому я хочу, чтобы в процессе тестировался журнал HRF, а в конце мне нужен XML-файл, содержащий <TestLog>...</TestLog>
выход Boost.Test (не <TestResult>
выход).
Обратите внимание, что мы запускаем как модульные, так и интеграционные тесты через Boost.Test, поэтому некоторые из них довольно продолжительны.
Я сделал это 🙂 После долгих проб и ошибок мне удалось найти достойный способ, чтобы фактическая работа по выводу выполнялась самой структурой Boost.Test, и все еще получать вывод XML в файл.
Ключ должен понять, что и как можно настроить в Boost.Test:
boost::iostream
и tee_filter
написать как в стандартный вывод, так и в файл.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;
};
}
}
}