Jak wysłać niestandardową wiadomość w Google C ++ Testing Framework?


83

Używam Google C ++ Testing Framework do testów jednostkowych mojego kodu. Używam Eclipse CDT z modułem C ++ Unit testing do analizy wyników.

Wcześniej użyłem CppUnit, który ma rodzinę makr CPPUNIT * _MESSAGE, które można nazwać tak:

CPPUNIT_ASSERT_EQUAL_MESSAGE("message",EXPECTED_VALUE,ACTUAL_VALUE)

I umożliwia wysyłanie niestandardowych wiadomości w celu przetestowania wyjścia.

Czy istnieje sposób na umieszczenie niestandardowego tekstu w wynikach testu Google?

(Najlepiej sposób, który mógłby obejmować komunikat do danych, które są odczytywane przez istniejące programy do automatycznego testowania jednostkowego przy użyciu testu Google).

Odpowiedzi:


160

Makra gtest zwracają strumień do wysyłania komunikatów diagnostycznych, gdy test się nie powiedzie.

EXPECT_TRUE(false) << "diagnostic message";

@ErikAronesty Czy zajrzałeś do źródła, aby sprawdzić, czy istnieje łatwy sposób na połączenie się z tymi danymi?
kayleeFrye_onDeck

2
Jeśli chcesz wydrukować tekst niezależnie od wyniku, po prostu zapisz go na standardowe wyjście. Ale zwykle prowadzi to do bardzo głośnych testów, z którymi trudno się pracuje.
Audrius Meskauskas,

FAIL () << "komunikat diagnostyczny"; działa w ten sam sposób, ale redukuje wygenerowane wyjście o kilka wierszy, ponieważ nie informuje o rzeczywistej wartości, wartości oczekiwanej itd., co robi dla wszystkich makr EXPECT_X (). Na wszelki wypadek, gdybyś chciał trochę zmniejszyć długość wydruku.
BallisticTomato

61

W obecnej wersji gtest nie ma sposobu, aby to zrobić czysto. Spojrzałem na kod i jedyne wyjście tekstowe (zawinięte w gtest "Wiadomości") jest wyświetlane, jeśli nie zaliczysz testu.

Jednak w pewnym momencie gtest zaczyna pojawiać printfsię na ekranie i możesz wykorzystać wyższy poziom, aby uzyskać kolory niezależne od platformy.

Oto zhakowane makro, które robi, co chcesz. Używa wewnętrznego kolorowania tekstu gtest. Oczywiście internal::przestrzeń nazw powinna wydawać dźwięki ostrzegawcze, ale hej, to działa.

Stosowanie:

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

  // or C++ style

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

Wynik:

Przykładowe dane wyjściowe

Kod:

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()

Dzięki, to jest poprawne rozwiązanie, IMHO. Ale czy mogę zasugerować dodanie a \nw PRINTF wewnątrz klasy? Dzieje się tak dlatego, że nie możemy łączyć linii z TEST_COUT tak jak robimy z std::cout, więc nie ma sensu pozwalać użytkownikowi dodawać jego \n. Mimo wszystko dziekuję!
HappyCactus

1
Niestety to podejście nie działa już z nowoczesnymi wersjami Google Test - testing::internal::ColoredPrintfnie jest już dostępne publicznie :(
AntonK

17

Jest na to dość prosty i hakerski sposób (bez konieczności zagłębiania się w klasy wewnętrzne lub tworzenia nowych klas niestandardowych).

Po prostu zdefiniuj makro:

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

i używaj GTEST_COUT(tak jak cout) w swoich testach:

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

I zobaczysz taki wynik:

wprowadź opis obrazu tutaj

Podziękowania dla @Martin Nowak za jego odkrycie.


5

Zapoznaj się z odpowiedzią Marka Lakaty, oto moja droga:

Krok 1: utwórz plik nagłówkowy, na przykład: gtest_cout.h

Kod:

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

Krok 2: użyj GOUTw swoim gtest

Stosowanie:

#include "gtest_cout.h"

TEST(xxx, yyy)
{
    GOUT("Hello world!");
}

ColouredPrintf stał się statyczny w najnowszej wersji, więc ten hack nie będzie już działać.
schwart

3

Powinieneś zdefiniować poniżej:

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

} logout;

używając tego:

logout.info() << "test: " << "log" << std::endl;

0

W zaawansowanych tematach googletest możesz użyć do tego kilku makr.

  • SUCCEED () SUCCEED() << "success/info message"; SUCCEED () wyświetla tylko twoją wiadomość i kontynuuje. Nie oznacza to zaliczenia testu. Jego wynik zostanie określony przez następujące twierdzenia.
  • FAIL () FAIL() << "test failure message"; FAIL () oznacza test jako zakończony niepowodzeniem, wyświetla komunikat, a następnie wraca z funkcji. Dlatego może być używany tylko w funkcjach zwracających void.
  • ADD_FAILURE () ADD_FAILURE() << "test failure message"; ADD_FAILURE () oznacza twój test jako nieudany i wyświetla twoją wiadomość. Nie powraca z funkcji wywołującej, a przepływ wykonania jest kontynuowany jak w przypadku serii makr EXPECT_.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.