Могу ли я проверить вывод моей программы с помощью форс-теста?

Как в:

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

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

person rturrado    schedule 23.03.2011    source источник


Ответы (2)


Да, вы можете сделать это, перенаправив 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()
person Björn Pollex    schedule 23.03.2011
comment
Красиво, Space_C0wb0y. Итак, давайте посмотрим, понимаю ли я, что там происходит. В конструкторе cout_redirect мы устанавливаем буфер потока cout для увеличения буфера выходного тестового потока. И мы сохраняем старый буфер потока cout. Все, что записывается с этого момента в cout, и до тех пор, пока cout_redirect не будет уничтожено, фактически записывается в буфер потока Boost. Когда cout_redirect уничтожается, мы сбрасываем буфер потока cout в его предыдущее значение, и у нас есть буфер потока ускорения со всем программным выводом, который мы хотели. - person rturrado; 23.03.2011
comment
Я думаю, что мы могли бы также сделать так, чтобы установить буфер потокового потока в буфер потока cout. В этом случае мы все равно получили бы вывод в cout, и мы могли бы проверить его с помощью потока boost. - person rturrado; 23.03.2011
comment
@rturrado: я не знаю, сработает ли это так, как ожидалось. Как только std::cout будет сброшен, буфер будет пуст, и output_test_stream не сможет позже проверить его содержимое. - person Björn Pollex; 23.03.2011
comment
Это можно сделать и для std::cerr. - person muman; 10.01.2021

Я несколько дней следил за ответом @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()

Для получения дополнительной информации прочитайте официальная документация.

person Hank    schedule 20.09.2013
comment
в вашем примере вы можете тестировать только operator<< реализации. ОП хочет явно захватить std::cout, поэтому ответ @Björn Pollex правильный. Однако, если требуется любой поток, а не только std::cout, то вы правы, просто используя output_test_stream. - person David Bellot; 22.08.2019