如何使用googletest捕获stdout/stderr?

Jan*_*egg 44 c++ unit-testing stdout googletest stderr

使用googletest框架时是否可以捕获stdout和stderr ?

例如,我想调用一个将错误写入控制台(stderr)的函数.现在,在测试中调用函数时,我想断言那里没有输出.

或者,也许我想测试错误行为,并希望在我(故意)产生错误时断言某个字符串被打印.

Hei*_*nzi 70

Googletest为此提供了以下功能:

testing::internal::CaptureStdout();
std::cout << "My test";
std::string output = testing::internal::GetCapturedStdout();
Run Code Online (Sandbox Code Playgroud)

  • 应该知道这是一个私有API,因此不受支持.我建议不要这样做 (7认同)
  • 我发现如果多次调用这会导致段错误,即使在不同的测试中也是如此,因此毫无价值。 (4认同)
  • testing :: internal :: CaptureStderr()也存在.例如:https://googletest.googlecode.com/svn/trunk/test/gtest-death-test_test.cc (3认同)
  • @NirFriedman 似乎必须在 _each_ 捕获之前调用 `::testing::internal::CaptureStdout()` 。 (3认同)

小智 30

我之前使用过此片段,在测试输出时将cout调用重定向到字符串流.希望它可能会引发一些想法.我之前从未使用过googletest.

// This can be an ofstream as well or any other ostream
std::stringstream buffer;

// Save cout's buffer here
std::streambuf *sbuf = std::cout.rdbuf();

// Redirect cout to our stringstream buffer or any other ostream
std::cout.rdbuf(buffer.rdbuf());

// Use cout as usual
std::cout << "Hello World";

// When done redirect cout to its old self
std::cout.rdbuf(sbuf);
Run Code Online (Sandbox Code Playgroud)

在重定向回原始输出之前,请使用google测试检查缓冲区中的输出.

  • 这对 googletest 不起作用,因为 gtest 使用 printf 直接转到 stdout,从而绕过您的重定向。但如果你想拦截 `cout &lt;&lt; ...` 的输出,这是一个很好的解决方案。我会创建一个辅助类来自动恢复析构函数中的原始streambuf... (2认同)

Fle*_*exo 6

避免这样做总是一个很好的设计理念。如果您真的想这样做,请执行以下操作:

#include <cstdio>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>

int main() {
   int fd = open("my_file.log", O_WRONLY|O_CREAT|O_TRUNC, 0660);
   assert(fd >= 0);
   int ret = dup2(fd, 1);
   assert(ret >= 0);
   printf("This is stdout now!\n");
   std::cout << "This is C++ iostream cout now!" << std::endl;
   close(fd);
}
Run Code Online (Sandbox Code Playgroud)

要使用 stderr 而不是 stdout 将 dup2 的第二个参数更改为 2。为了不通过文件进行捕获,您可以使用管道对。