GoogleTest: Wie überspringe ich einen Test?

118

Verwenden von Google Test 1.6 (Windows 7, Visual Studio C ++). Wie kann ich einen bestimmten Test ausschalten? (aka wie kann ich verhindern, dass ein Test ausgeführt wird). Kann ich etwas anderes tun, als den gesamten Test zu kommentieren?

Benutzer
quelle

Antworten:

176

In den Dokumenten für Google Test 1.7 wird Folgendes vorgeschlagen :

"Wenn Sie einen fehlerhaften Test haben, den Sie nicht sofort beheben können, können Sie das Präfix DISABLED_ zu seinem Namen hinzufügen. Dadurch wird es von der Ausführung ausgeschlossen."

Beispiele:

// Tests that Foo does Abc.
TEST(FooTest, DISABLED_DoesAbc) { ... }

class DISABLED_BarTest : public ::testing::Test { ... };

// Tests that Bar does Xyz.
TEST_F(DISABLED_BarTest, DoesXyz) { ... }
Rechnung
quelle
1
habe es gerade auch gefunden und filtert
User
@ Bill, ich habe es gefunden, kurz bevor du deinen Kommentar gepostet hast ... (und ich habe es auch als Antwort angegeben). Ich habe dann meinen Kommentar entfernt und festgestellt, dass er veraltet ist ... aber das sind einige wirklich gute Informationen! +1
Kiril
67

Sie können auch eine Teilmenge von Tests gemäß der Dokumentation ausführen :

Ausführen einer Teilmenge der Tests

Standardmäßig führt ein Google Test-Programm alle vom Benutzer definierten Tests aus. Manchmal möchten Sie nur eine Teilmenge der Tests ausführen (z. B. zum Debuggen oder schnellen Überprüfen einer Änderung). Wenn Sie die Umgebungsvariable GTEST_FILTER oder das Flag --gtest_filter auf eine Filterzeichenfolge setzen, führt Google Test nur die Tests aus, deren vollständige Namen (in Form von TestCaseName.TestName) mit dem Filter übereinstimmen.

Das Format eines Filters ist eine ':' - getrennte Liste von Platzhaltermustern (als positive Muster bezeichnet), gefolgt von einer '-' und einer weiteren ':' - getrennten Musterliste (als negative Muster bezeichnet). Ein Test stimmt genau dann mit dem Filter überein, wenn er mit einem der positiven Muster übereinstimmt, jedoch nicht mit einem der negativen Muster.

Ein Muster kann '*' (entspricht einer beliebigen Zeichenfolge) oder '?' (Entspricht einem einzelnen Zeichen). Der Einfachheit halber kann der Filter '* -NegativePatterns' auch als '-NegativePatterns' geschrieben werden.

Beispielsweise:

./foo_test Has no flag, and thus runs all its tests.
./foo_test --gtest_filter=* Also runs everything, due to the single match-everything * value.
./foo_test --gtest_filter=FooTest.* Runs everything in test case FooTest.
./foo_test --gtest_filter=*Null*:*Constructor* Runs any test whose full name contains either "Null" or "Constructor".
./foo_test --gtest_filter=-*DeathTest.* Runs all non-death tests.
./foo_test --gtest_filter=FooTest.*-FooTest.Bar Runs everything in test case FooTest except FooTest.Bar. 

Nicht die schönste Lösung, aber es funktioniert.

Kiril
quelle
24

Sie können das GTEST_SKIP()Makro jetzt verwenden , um einen Test zur Laufzeit bedingt zu überspringen. Beispielsweise:

TEST(Foo, Bar)
{
    if (blah)
        GTEST_SKIP();

    ...
}

Beachten Sie, dass dies eine sehr aktuelle Funktion ist. Daher müssen Sie möglicherweise Ihre GoogleTest-Bibliothek aktualisieren, um sie verwenden zu können.

Peter Bloomfield
quelle
Diese Funktion ist noch nicht freigegeben. Es ist unwahrscheinlich, dass es in einem 1.8.x-Zweig enthalten sein wird, da dort nur Korrekturen akzeptiert werden. 1.9 ist noch nicht verfügbar, noch nicht einmal angekündigt.
Okroquette
2
GTEST_SKIP()ist ab 1.10.0 verfügbar.
Mattdibi
Leider ist die Dokumentation dazu immer noch knapp. Es scheint auch so zu sein GTEST_SKIP_("some message")(beachten Sie den nachfolgenden Unterstrich)
Matthäus Brandl
19

Hier ist der Ausdruck, um Tests einzuschließen, deren Namen die Zeichenfolgen foo1 oder foo2 enthalten, und Tests auszuschließen, deren Namen die Zeichenfolgen bar1 oder bar2 enthalten:

--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*
Ashutosh
quelle
10

Ich mache es lieber im Code:

// Run a specific test only
//testing::GTEST_FLAG(filter) = "MyLibrary.TestReading"; // I'm testing a new feature, run something quickly

// Exclude a specific test
testing::GTEST_FLAG(filter) = "-MyLibrary.TestWriting"; // The writing test is broken, so skip it

Ich kann entweder beide Zeilen auskommentieren, um alle Tests auszuführen, die erste Zeile auskommentieren, um eine einzelne Funktion zu testen, die ich untersuche / an der ich arbeite, oder die zweite Zeile auskommentieren, wenn ein Test fehlerhaft ist, aber ich möchte alles andere testen.
Sie können eine Reihe von Funktionen auch testen / ausschließen, indem Sie Platzhalter verwenden und eine Liste "MyLibrary.TestNetwork *" oder "-MyLibrary.TestFileSystem *" schreiben.

Pilkch
quelle
Dies ist eine großartige Lösung. Ich verwende es, um einige Tests standardmäßig auszuschließen, wenn der Filter leer ist. Sie können mit aktiviert werden export GTEST_FILTER='*'.
Timmmm
Eigentlich funktioniert das nicht, weil der Standard " *" nicht "" ist. Stattdessen verwende ich einfach eine andere Umgebungsvariable, die den Filter überschreibt.
Timmmm
Wo haben Sie den "Filter" definiert? Ist es eine Schnur?
Beasone
Ich definiere es nicht, also denke ich, dass es ein globales sein muss, das von gtest / gtest.h enthalten ist.
Pilkch
6

Wenn mehr als ein Test benötigt wird, wird übersprungen

--gtest_filter=-TestName.*:TestName.*TestCase
Vijay C.
quelle
4

Für einen anderen Ansatz können Sie Ihre Tests in eine Funktion einbinden und zur Laufzeit normale bedingte Prüfungen verwenden, um sie nur auszuführen, wenn Sie möchten.

#include <gtest/gtest.h>

const bool skip_some_test = true;

bool some_test_was_run = false;

void someTest() {
   EXPECT_TRUE(!skip_some_test);
   some_test_was_run = true;
}

TEST(BasicTest, Sanity) {
   EXPECT_EQ(1, 1);
   if(!skip_some_test) {
      someTest();
      EXPECT_TRUE(some_test_was_run);
   }
}

Dies ist nützlich für mich, da ich versuche, einige Tests nur auszuführen, wenn ein System Dual-Stack-IPv6 unterstützt.

Technisch gesehen sollte dieses Dualstack-Zeug eigentlich kein Unit-Test sein, da es vom System abhängt. Aber ich kann keine Integrationstests durchführen, bis ich getestet habe, dass sie trotzdem funktionieren, und dies stellt sicher, dass keine Fehler gemeldet werden, wenn es nicht der Fehler des Codes ist.

Was den Test betrifft, habe ich Stub-Objekte, die die Unterstützung eines Systems für Dualstack (oder das Fehlen von) simulieren, indem sie gefälschte Sockets konstruieren.

Der einzige Nachteil ist, dass sich die Testausgabe und die Anzahl der Tests ändern, was zu Problemen mit etwas führen kann, das die Anzahl der erfolgreichen Tests überwacht.

Sie können auch ASSERT_ * anstelle von EQUAL_ * verwenden. Bestätigen Sie den Rest des Tests, wenn er fehlschlägt. Verhindert, dass viele redundante Inhalte auf die Konsole übertragen werden.

David C. Bishop
quelle
4

Ich hatte das gleiche Bedürfnis nach bedingten Tests und fand eine gute Problemumgehung. Ich habe ein Makro TEST_C definiert, das wie ein TEST_F-Makro funktioniert, aber es hat einen dritten Parameter, einen booleschen Ausdruck, der die Laufzeit in main.cpp ausgewertet hat, bevor die Tests gestartet werden. Tests, die false bewerten, werden nicht ausgeführt. Das Makro ist hässlich, aber es sieht aus wie:

#pragma once
extern std::map<std::string, std::function<bool()> >* m_conditionalTests;
#define TEST_C(test_fixture, test_name, test_condition)\
class test_fixture##_##test_name##_ConditionClass\
{\
    public:\
    test_fixture##_##test_name##_ConditionClass()\
    {\
        std::string name = std::string(#test_fixture) + "." + std::string(#test_name);\
        if (m_conditionalTests==NULL) {\
            m_conditionalTests = new std::map<std::string, std::function<bool()> >();\
        }\
        m_conditionalTests->insert(std::make_pair(name, []()\
        {\
            DeviceInfo device = Connection::Instance()->GetDeviceInfo();\
            return test_condition;\
        }));\
    }\
} test_fixture##_##test_name##_ConditionInstance;\
TEST_F(test_fixture, test_name)

Darüber hinaus benötigen Sie in Ihrer main.cpp diese Schleife, um die Tests auszuschließen, die false auswerten:

// identify tests that cannot run on this device
std::string excludeTests;
for (const auto& exclusion : *m_conditionalTests)
{
    bool run = exclusion.second();
    if (!run)
    {
        excludeTests += ":" + exclusion.first;
    }
}

// add the exclusion list to gtest
std::string str = ::testing::GTEST_FLAG(filter);
::testing::GTEST_FLAG(filter) = str + ":-" + excludeTests;

// run all tests
int result = RUN_ALL_TESTS();
Jiri Zbranek
quelle
Wie haben Sie "Filter" in std :: string str = :: testing :: GTEST_FLAG (Filter) definiert?
Beasone