What is the better way to generate test report in a file using BOOST.Test?
I know by default report is directed to standard-error, and so one has to redirect it to a file. My question is shall we do this inside a global fixture? Which isn't seem to be working for me some how.
This is what i tried -
struct MyConfig开发者_Python百科
{
MyConfig()
: testReport("fileName.log")
{
if(!testReport.fail())
original = std::cerr.rdbuf(testReport.rdbuf());
}
~MyConfig()
{
cerr.rdbuf(original);
testReport.close();
}
ofstream testReport;
streambuf* original;
};
BOOST_GLOBAL_FIXTURE(MyConfig);
After running the test, report outputs on console only, though a 0kb file is created with the given name.
With Boost 1.44.0 (and maybe later versions) you need the following code to create a global fixture which redirects the output of the test program to a file named after the master testsuite in which the test is included (see Boost Documentation)
#include <boost/test/unit_test.hpp>
#include <string>
#include <fstream>
struct LogToFile
{
LogToFile()
{
std::string logFileName(boost::unit_test::framework::master_test_suite().p_name);
logFileName.append(".xml");
logFile.open(logFileName.c_str());
boost::unit_test::unit_test_log.set_stream(logFile);
}
~LogToFile()
{
boost::unit_test::unit_test_log.test_finish();
logFile.close();
boost::unit_test::unit_test_log.set_stream(std::cout);
}
std::ofstream logFile;
};
BOOST_GLOBAL_FIXTURE(LogToFile);
In this example logFile
is not a static member like in the answer provided by Steve Townsend because declaring logFile
as static member resulted in wrongly generated XML and accessing the fixture struct is not thread-safe this way.
However, there seems to be a bug in Boost 1.44.0 which also results in incorrect XML output getting generated if logFile
is not a static member of the fixture struct (probably the same bug I mentioned before).
To fix this the line logFile << "</TestLog>" << std::flush;
is needed before closing the filestream in the destructor to generate valid XML.
Thanks to @Wracky (comment below) I replaced the line logFile << "</TestLog>" << std::flush;
with boost::unit_test::unit_test_log.test_finish();
which is a much cleaner solution than writing the tag manually.
NOTE: the tests are run with the following parameters: --output_format=XML --log_level=all --report_level=no
.
This enables the usage of the resulting XML files with the xUnit plugin for the continuous integration server Jenkins.
For Completeness:
You don't have to redirect the input yourself if you don't want to. You can also specify a logfile via command line arguments:
C:\MyTest.exe --log_sink=fileName.log
Took me a while to find. Hope this helps!
You could try this alternative, adapted from here and alleged to work on Boost 1.34.1. This seems to be more as Boost intends - see the usage of a results stream overrider.
//
// run_tests.cc
//
#define BOOST_AUTO_TEST_MAIN
#include <iostream>
#include <fstream>
#include <cassert>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/results_reporter.hpp>
std::ofstream ReportRedirector::out;
struct ReportRedirector
{
ReportRedirector()
{
out.open("fileName.log");
assert( out.is_open() );
boost::unit_test::results_reporter::set_stream(out);
}
private:
static std::ofstream out;
};
BOOST_GLOBAL_FIXTURE(ReportRedirector)
精彩评论