使用 BOOST.Test 在文件中生成测试报告的更好方法是什么?

发布于 2024-09-24 11:00:35 字数 502 浏览 4 评论 0原文

我知道默认情况下报告会定向到标准错误,因此必须将其重定向到文件。 我的问题是我们应该在全球固定装置中执行此操作吗?这似乎对我不起作用。

这就是我尝试过的 -

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);

运行测试后,仅在控制台上报告输出,尽管使用给定名称创建了 0kb 文件。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

为你拒绝所有暧昧 2024-10-01 11:00:35

使用 Boost 1.44.0(可能还有更高版本),您需要以下代码来创建一个全局固定装置,该全局固定装置将测试程序的输出重定向到以包含测试的主测试套件命名的文件(请参阅 Boost文档

#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);

在此示例中 logFile 不是静态成员,如 Steve Townsend 因为将 logFile 声明为静态成员导致错误生成的 XML 和访问固定结构的方式不是线程安全的。

但是,Boost 1.44.0 中似乎存在一个错误,如果 logFile 不是固定结构的静态成员,也会导致生成不正确的 XML 输出(可能与我提到的错误相同)前)。
要解决此问题,请使用 logFile << 行“” <<在析构函数中关闭文件流之前需要 std::flush; 以生成有效的 XML。

感谢@Wracky(下面的评论)我替换了行 logFile << “” << std::flush;boost::unit_test::unit_test_log.test_finish(); 这是比手动编写标签更干净的解决方案。

注意:测试使用以下参数运行:--output_format=XML --log_level=all --report_level=no
这样就可以通过 xUnit 插件 使用生成的 XML 文件持续集成服务器 Jenkins

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.

惜醉颜 2024-10-01 11:00:35

为了完整性:

如果您不愿意,则不必自己重定向输入。
您还可以通过命令行参数指定日志文件:

C:\MyTest.exe --log_sink=fileName.log

我花了一段时间才找到。希望这有帮助!

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!

﹏雨一样淡蓝的深情 2024-10-01 11:00:35

您可以尝试这个替代方案,改编自此处,据称适用于 Boost 1.34.1。这似乎更符合 Boost 的意图 - 请参阅结果流重写器的用法。

//
// 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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文