我能使用boost test来检查我的程序输出吗?

15

就像这样:

void f()
{
  cout << "blah" << endl;
}

BOOST_AUTO_TEST_CASE(f)
{
  f();
  // This would be a beauty
  // BOOST_CHECK_PROGRAM_OUTPUT_MATCH("blah");
}
2个回答

26

是的,您可以通过将 std::cout 重定向到一个 boost::test_tools::output_test_stream 来实现,并提供了特殊方法来比较输出。为了确保 std::cout 始终被正确恢复,您可以使用自定义结构体,如下面的示例所示。

#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>
#include <boost/test/output_test_stream.hpp>
#include <iostream>

BOOST_AUTO_TEST_SUITE( TestSuite1 )

struct cout_redirect {
    cout_redirect( std::streambuf * new_buffer ) 
        : old( std::cout.rdbuf( new_buffer ) )
    { }

    ~cout_redirect( ) {
        std::cout.rdbuf( old );
    }

private:
    std::streambuf * old;
};

BOOST_AUTO_TEST_CASE( test1 )
{
    boost::test_tools::output_test_stream output;
    {
        cout_redirect guard( output.rdbuf( ) );

        std::cout << "Test" << std::endl;
    }

    BOOST_CHECK( output.is_equal( "Test\n" ) );
}

BOOST_AUTO_TEST_SUITE_END()

美丽的,Space_C0wb0y。那么让我们看看发生了什么。在cout_redirect构造函数中,我们将cout流缓冲区设置为boost输出测试流缓冲区。并保存旧的cout流缓冲区。从那时起,在cout中写入的任何内容,直到cout_redirect被销毁,实际上都被写入到boost流缓冲区中。当cout_redirect被销毁时,我们将cout流缓冲区重置为其先前的值,并拥有了一个包含所有所需程序输出的boost流缓冲区。 - rturrado
我想,我们还可以将boost流缓冲区设置为cout流缓冲区。在这种情况下,我们仍然可以在cout中获得输出,并且我们可以使用boost流进行检查。 - rturrado
1
@rturrado:我不知道这是否能按预期工作。一旦 std::cout 被刷新,缓冲区将为空,output_test_stream 以后将无法检查其内容。 - Björn Pollex

4

我已经跟随 @Björn Pollex 的答案进行了一些日子。但有一天我发现不需要那样做。只需使用 boost::test_tools::output_test_stream 即可。

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/output_test_stream.hpp>

BOOST_AUTO_TEST_SUITE(TestSuite1)

BOOST_AUTO_TEST_CASE(test1)
{
    boost::test_tools::output_test_stream output;
    output << "Test";

    BOOST_CHECK(output.is_equal("Test"));
}

BOOST_AUTO_TEST_SUITE_END()

如需更多信息,请阅读官方文档


3
在您的示例中,您只能测试 operator<< 的实现。OP想要明确捕获 std::cout,因此 @Björn Pollex 的答案是正确的。但是,如果需要任何流,并非仅限于 std::cout,那么您关于只使用 output_test_stream 是正确的。 - David Bellot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接