test google c++ unit-testing stdout stderr googletest

c++ - Cómo capturar stdout/stderr con googletest?



google test install (4)

En lugar de hacer esto, use la inyección de dependencia para eliminar el uso directo de std::cout . En el código de prueba, utilice un objeto simulado de la clase std:ostringstream como objeto simulado en lugar de std::cout real.

Entonces en vez de esto:

void func() { ... std::cout << "message"; ... } int main (int argc, char **argv) { ... func(); ... }

tengo esto:

void func(std::ostream &out) { ... out << "message"; ... } int main(int argc, char **argv) { ... func(std::cout); ... }

¿Es posible capturar stdout y stderr cuando se utiliza el marco googletest ?

Por ejemplo, me gustaría llamar a una función que escribe errores en la consola (stderr). Ahora, cuando llame a la función en las pruebas, quiero afirmar que no aparece ningún resultado allí.

O bien, tal vez quiero probar el comportamiento de error y quiero afirmar que se imprime una determinada cadena cuando (deliberadamente) produzco un error.


Evitar tener que hacer esto siempre es una buena idea de diseño. Si realmente quieres hacerlo, lo siguiente funciona:

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

Para usar stderr en lugar de stdout, cambie el segundo argumento a dup2 para que sea 2. Para capturar sin pasar por un archivo, podría usar un par de tubos en su lugar.


Googletest ofrece funciones para esto:

testing::internal::CaptureStdout(); std::cout << "My test" std::string output = testing::internal::GetCapturedStdout();


He usado este fragmento antes para redirigir las llamadas de cout a un flujo de cadenas al probar el resultado. Con suerte, podría generar algunas ideas. Nunca antes había usado 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);

Antes de redireccionar a la salida original, use su prueba de google para verificar el resultado en el búfer.