¿Cómo enviar un mensaje personalizado en Google C ++ Testing Framework?

81

Utilizo Google C ++ Testing Framework para la prueba unitaria de mi código. Utilizo Eclipse CDT con el módulo de prueba de unidad C ++ para el análisis de salida.

Anteriormente usé CppUnit , tiene la familia de macros CPPUNIT * _MESSAGE que podría llamarse así:

CPPUNIT_ASSERT_EQUAL_MESSAGE("message",EXPECTED_VALUE,ACTUAL_VALUE)

Y permite enviar mensajes personalizados para probar la salida.

¿Hay alguna forma de incluir texto personalizado en la salida de prueba de Google?

(Preferiblemente la forma en que podría incluir mensajes a datos que son leídos por programas existentes para pruebas unitarias automatizadas usando la prueba de Google).

Yuriy Petrovskiy
fuente

Respuestas:

157

Las macros gtest devuelven una secuencia para generar mensajes de diagnóstico cuando falla una prueba.

EXPECT_TRUE(false) << "diagnostic message";
usuario2093113
fuente
@ErikAronesty ¿Ha echado un vistazo a la fuente para ver si hay una forma sencilla de interactuar con esos datos?
kayleeFrye_onDeck
2
Si necesita imprimir el texto independientemente del resultado, simplemente escríbalo en stdout. Pero esto suele dar lugar a pruebas muy ruidosas, difíciles de trabajar.
Audrius Meskauskas
FAIL () << "mensaje de diagnóstico"; funciona de la misma manera, pero reduce la salida generada en unas pocas líneas, ya que no le informa sobre el valor real, el valor esperado, etc., lo que hace para todas las macros EXPECT_X (). En caso de que desee reducir un poco la longitud de salida.
BallisticTomato
61

No hay forma de hacerlo limpiamente en la versión actual de gtest. Miré el código y la única salida de texto (envuelta en gtest "Mensajes") se muestra si falla una prueba.

Sin embargo, en algún momento, gtest comienza a aparecer printfen la pantalla, y puede aprovechar el nivel superior para obtener colores que son independientes de la plataforma.

Aquí tienes una macro pirateada para hacer lo que quieras. Esto utiliza el mejor color de texto interno. Por supuesto, el internal::espacio de nombres debería estar sonando con campanas de advertencia, pero bueno, funciona.

Uso:

TEST(pa_acq,Foo)
{
  // C style
  PRINTF("Hello world \n");

  // or C++ style

  TEST_COUT << "Hello world" << std::endl;
}

Salida:

Salida de ejemplo

Código:

namespace testing
{
 namespace internal
 {
  enum GTestColor {
      COLOR_DEFAULT,
      COLOR_RED,
      COLOR_GREEN,
      COLOR_YELLOW
  };

  extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
 }
}
#define PRINTF(...)  do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[          ] "); testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } while(0)

// C++ stream interface
class TestCout : public std::stringstream
{
public:
    ~TestCout()
    {
        PRINTF("%s",str().c_str());
    }
};

#define TEST_COUT  TestCout()
Mark Lakata
fuente
Gracias, esta es la solución correcta, en mi humilde opinión. Pero, ¿puedo sugerir agregar un \nen PRINTF dentro de la clase? eso es porque no podemos unir líneas con TEST_COUT como lo hacemos con std::cout, por lo que es inútil dejar que el usuario agregue el suyo \n. ¡Gracias de todos modos!
HappyCactus
1
Desafortunadamente, este enfoque ya no funciona con las versiones modernas de Google Test; testing::internal::ColoredPrintfya no está disponible para el público :(
AntonK
15

Hay una forma bastante simple y hacky de hacerlo (sin necesidad de sumergirse en clases internas o crear nuevas clases personalizadas).

Simplemente defina una macro:

#define GTEST_COUT std::cerr << "[          ] [ INFO ]"

y use GTEST_COUT(como cout) en sus pruebas:

GTEST_COUT << "Hello World" << std::endl;

Y verás tal resultado:

ingrese la descripción de la imagen aquí

El crédito es para @Martin Nowak por su hallazgo.

Solo sombra
fuente
5

Consulte la respuesta de Mark Lakata, aquí está mi camino:

Paso 1: cree un archivo de encabezado, por ejemplo: gtest_cout.h

Código:

#ifndef _GTEST_COUT_H_
#define _GTEST_COUT_H_

#include "gtest/gtest.h"

namespace testing
{
namespace internal
{
enum GTestColor
{
    COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW
};
extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
}
}

#define GOUT(STREAM) \
    do \
    { \
        std::stringstream ss; \
        ss << STREAM << std::endl; \
        testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[          ] "); \
        testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, ss.str().c_str()); \
    } while (false); \

#endif /* _GTEST_COUT_H_ */

Paso 2: utilícelo GOUTen su gtest

Uso:

#include "gtest_cout.h"

TEST(xxx, yyy)
{
    GOUT("Hello world!");
}
yosolina
fuente
ColouredPrintf se ha hecho estático en una versión reciente, por lo que este truco ya no funcionará.
Schwart
3

Debe definir lo siguiente:

static class LOGOUT {
public:
    LOGOUT() {}
    std::ostream&  info() {
        std::cout << "[info      ] ";
        return std::cout;
    }

} logout;

usando esto:

logout.info() << "test: " << "log" << std::endl;
허영주
fuente