Wie sende ich eine benutzerdefinierte Nachricht in Google C ++ Testing Framework?

81

Ich verwende Google C ++ Testing Framework zum Unit-Testen meines Codes. Ich verwende Eclipse CDT mit C ++ Unit-Testmodul für die Ausgabeanalyse.

Zuvor habe ich CppUnit verwendet. Es hat die Makrofamilie CPPUNIT * _MESSAGE , die folgendermaßen aufgerufen werden kann:

CPPUNIT_ASSERT_EQUAL_MESSAGE("message",EXPECTED_VALUE,ACTUAL_VALUE)

Und ermöglicht das Senden von benutzerdefinierten Nachrichten zum Testen der Ausgabe.

Gibt es eine Möglichkeit, benutzerdefinierten Text in die Google-Testausgabe aufzunehmen?

(Vorzugsweise die Art und Weise, wie Nachrichten an Daten gesendet werden können, die von vorhandenen Programmen für automatisierte Komponententests mit Google Test gelesen werden.)

Yuriy Petrovskiy
quelle

Antworten:

157

Die gtest-Makros geben einen Stream zur Ausgabe von Diagnosemeldungen zurück, wenn ein Test fehlschlägt.

EXPECT_TRUE(false) << "diagnostic message";
user2093113
quelle
@ErikAronesty Haben Sie in der Quelle nachgesehen, ob es eine einfache Möglichkeit gibt, mit diesen Daten zu kommunizieren?
KayleeFrye_onDeck
2
Wenn Sie den Text unabhängig vom Ergebnis drucken müssen, schreiben Sie ihn einfach in stdout. Dies führt jedoch normalerweise zu sehr lauten Tests, mit denen schwer zu arbeiten ist.
Audrius Meskauskas
FAIL () << "Diagnosemeldung"; funktioniert genauso, reduziert jedoch die generierte Ausgabe um einige Zeilen, da Sie nicht über den tatsächlichen Wert, den erwarteten Wert usw. informiert werden, was für alle EXPECT_X () -Makros der Fall ist. Nur für den Fall, dass Sie die Ausgabelänge etwas reduzieren möchten.
BallisticTomato
61

In der aktuellen Version von gtest gibt es keine Möglichkeit, dies sauber zu machen. Ich schaute auf dem Code, und die einzige Textausgabe (eingewickelt in Gtest „Nachrichten“) wird angezeigt , wenn Sie nicht einen Test.

Irgendwann wird gtest jedoch printfauf dem Bildschirm angezeigt, und Sie können die darüber liegende Stufe nutzen, um plattformunabhängige Farben zu erhalten.

Hier ist ein gehacktes Makro, um zu tun, was Sie wollen. Dies verwendet die gtest-interne Textfarbe. Natürlich sollte der internal::Namespace von Warnglocken ausgehen, aber hey, es funktioniert.

Verwendung:

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

  // or C++ style

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

Ausgabe:

Beispielausgabe

Code:

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
quelle
Danke, das ist die richtige Lösung, IMHO. Aber kann ich vorschlagen, \ninnerhalb der Klasse ein PRINTF hinzuzufügen ? Das liegt daran, dass wir mit TEST_COUT keine Zeilen verbinden können, wie wir es tun. Daher std::coutist es sinnlos, den Benutzer seine hinzufügen zu lassen \n. Trotzdem danke!
HappyCactus
1
Leider funktioniert dieser Ansatz mit modernen Versionen von Google Test testing::internal::ColoredPrintfnicht mehr - ist für die Öffentlichkeit nicht mehr verfügbar :(
AntonK
15

Es gibt eine recht einfache und hackige Möglichkeit, dies zu tun (ohne in interne Klassen eintauchen oder neue benutzerdefinierte Klassen erstellen zu müssen).

Definieren Sie einfach ein Makro:

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

und verwenden Sie GTEST_COUT(genau wie cout) in Ihren Tests:

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

Und Sie werden ein solches Ergebnis sehen:

Geben Sie hier die Bildbeschreibung ein

Dank geht an @Martin Nowak für seine Entdeckung.

Nur Schatten
quelle
5

Beziehen Sie sich auf Mark Lakatas Antwort, hier ist mein Weg:

Schritt 1: Erstellen Sie eine Header-Datei, zum Beispiel: gtest_cout.h

Code:

#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_ */

Schritt 2: Verwenden Sie GOUTin Ihrem gtest

Verwendung:

#include "gtest_cout.h"

TEST(xxx, yyy)
{
    GOUT("Hello world!");
}
Yosolin
quelle
ColoredPrintf wurde in einer neueren Version statisch gemacht, sodass dieser Hack nicht mehr funktioniert.
Schwart
3

Sie sollten Folgendes definieren:

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

} logout;

mit diesem:

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