C++单元测试检查输出是否正确

8
如果我想编写自己的test.cpp来检查另一个.cpp文件是否按照我的要求输出,是否有不需要显式打印的方法可以做到这一点?
换句话说,是否存在类似于 "redirecting standard output" 这样的东西?
assert(output_of_file_being_tested, "this is the correct output");

其中output_of_file_being_tested是被认为应该使用“cout”输出的内容。


1
你可以类似这样做:https://dev59.com/X2kw5IYBdhLWcg3wE2hA - Michael Albers
2
如果避免直接写入像 std::cout 这样的内容,而是写入 std::ostream& 引用,则代码更易于测试。然后测试框架可以传递 std::ostringstream 对象,而应用程序则传递 std::cout - Galik
2个回答

9
解决方案并不是硬编码输出流。以某种方式将对 std::ostream 的引用传递给您的代码,并在测试环境中使用 std::stringstream 收集输出。
例如,这是“另一个 .cpp” 文件的内容:
void toBeTested(std::ostream& output) {
        output << "this is the correct output";
}

因此,在您的生产/发布代码中,您可以将std::cout传递给该函数:

void productionCode() {
        toBeTested(std::cout);
}

在测试环境中,您可以收集输出到一个字符串流中并检查其正确性:
// test.cpp
#include <sstream>
#include <cassert>

void test() {
        std::stringstream ss;
        toBeTested(ss);
        assert(ss.str() == "this is the correct output");
}

0
除了上面Sergey的好答案之外,您可以选择将std::cout作为默认参数。因此,如果您有以下代码:
// Only need console output
using std::cout;
...
void toBeTested()
{
    cout << "This is the correct output.";
}

而且它被用于许多地方(或将来可能经常使用):

int main()
{
    ...
    toBeTested();
    ...
    toBeTested();
    ...
    // And so on...
    return 0;
}

为了避免破坏大量代码并保持简单的接口,您可以将上述函数转换为:
using std::cout;
...
void toBeTested(std::ostream& cout = std::cout)
{
    cout << "This is the correct output.";
}

而你的main函数不需要修改。
请注意,该函数的cout现在会覆盖全局作用域的cout。因此,这个cout可以是任何输出流,不会干扰全局cout

现在你可以像上面那样测试它了!

#include <sstream>
#include <cassert>

...

void testMyFunctionDisplay()
{
    // Arrange
    std::ostringstream output_buffer;

    // Act
    toBeTested(output_buffer);

    // Assert
    assert(output_buffer.str() == "This is the correct output.");
}

然而,并不需要每个函数都这样做。


如果我们想将函数的输出重定向到其他输出流中,这将非常有用:

  • 字符串流:如果您想在程序中的其他地方使用输出,例如测试模块或其他目的。
  • 文件:如果您希望在程序终止后仍保留输出。

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