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
{
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.
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)
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!
来源:https://stackoverflow.com/questions/3786639/what-is-the-better-way-to-generate-test-report-in-a-file-using-boost-test