GoogleTest: Jak pominąć test?

119

Korzystanie z Google Test 1.6 (Windows 7, Visual Studio C ++). Jak mogę wyłączyć dany test? (aka jak mogę zapobiec uruchomieniu testu). Czy jest coś, co mogę zrobić poza skomentowaniem całego testu?

Użytkownik
źródło

Odpowiedzi:

177

W docs dla Google testu 1,7 sugerują :

„Jeśli masz uszkodzony test, którego nie możesz naprawić od razu, możesz dodać przedrostek DISABLED_ do jego nazwy. Spowoduje to wykluczenie go z wykonywania”.

Przykłady:

// 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) { ... }
Rachunek
źródło
1
właśnie go znalazłem i filtruje
Użytkownik
@Bill, znalazłem to tuż przed opublikowaniem komentarza ... (i podałem go jako odpowiedź). Następnie usunąłem swój komentarz, uznając, że jest przestarzały ... ale to naprawdę dobra informacja! +1
Kiril
67

Możesz również uruchomić podzbiór testów , zgodnie z dokumentacją:

Przeprowadzanie podzbioru testów

Domyślnie program Google Test uruchamia wszystkie testy zdefiniowane przez użytkownika. Czasami chcesz uruchomić tylko podzbiór testów (np. W celu debugowania lub szybkiej weryfikacji zmiany). Jeśli ustawisz zmienną środowiskową GTEST_FILTER lub flagę --gtest_filter na ciąg filtru, Google Test uruchomi tylko testy, których pełne nazwy (w postaci TestCaseName.TestName) będą zgodne z filtrem.

Format filtru to oddzielona lista wzorców wieloznacznych (zwanych wzorcami dodatnimi) „:”, po których opcjonalnie występuje znak „-” i inna lista wzorców oddzielonych „:” (nazywanych wzorcami negatywnymi). Test dopasowuje filtr wtedy i tylko wtedy, gdy pasuje do któregokolwiek z pozytywnych wzorców, ale nie pasuje do żadnego z negatywnych wzorców.

Wzorzec może zawierać „*” (pasuje do dowolnego ciągu) lub „?” (dopasowuje dowolny pojedynczy znak). Dla wygody filtr „* -NegativePatterns” można również zapisać jako „-NegativePatterns”.

Na przykład:

./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. 

Nie najładniejsze rozwiązanie, ale działa.

Kiril
źródło
24

Możesz teraz użyć GTEST_SKIP()makra, aby warunkowo pominąć test w czasie wykonywania. Na przykład:

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

    ...
}

Pamiętaj, że jest to bardzo nowa funkcja, więc może być konieczne zaktualizowanie biblioteki GoogleTest, aby z niej korzystać.

Peter Bloomfield
źródło
Ta funkcja nie została jeszcze wydana. Jest mało prawdopodobne, że zostanie uwzględniony w gałęzi 1.8.x, ponieważ akceptowane są tam tylko poprawki. 1.9 nie jest jeszcze dostępny, nawet nie ogłoszono w tej chwili.
ocroquette
2
GTEST_SKIP()jest dostępny od 1.10.0.
mattdibi
Niestety, wciąż brakuje dokumentacji na ten temat. Wydaje się, że jest też GTEST_SKIP_("some message")(zwróć uwagę na podkreślenie na końcu)
Matthäus Brandl
19

Oto wyrażenie, które włącza testy, których nazwy zawierają ciągi foo1 lub foo2 i wyklucza testy, których nazwy zawierają ciągi bar1 lub bar2:

--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*
Ashutosh
źródło
10

Wolę robić to w kodzie:

// 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

Mogę skomentować obie linie, aby uruchomić wszystkie testy, odkomentować pierwszą linię, aby przetestować pojedynczą funkcję, którą badam / nad którą pracuję, lub odkomentować drugą linię, jeśli test jest uszkodzony, ale chcę przetestować wszystko inne.
Możesz także przetestować / wykluczyć zestaw funkcji, używając symboli wieloznacznych i pisząc listę „MyLibrary.TestNetwork *” lub „-MyLibrary.TestFileSystem *”.

pilkch
źródło
To świetne rozwiązanie. Używam go do domyślnego wykluczania niektórych testów, jeśli filtr jest pusty. Można je włączyć za pomocą export GTEST_FILTER='*'.
Timmmm,
Właściwie to nie działa, ponieważ wartość domyślna to *„nie”. Zamiast tego użyję innej zmiennej środowiskowej, która zastępuje filtr.
Timmmm,
Gdzie zdefiniowałeś „filtr”? Czy to jest ciąg?
beasone
Nie definiuję tego, więc myślę, że musi to być globalny plik z gtest / gtest.h?
pilkch
6

Jeśli potrzeba więcej niż jednego testu, należy pominąć

--gtest_filter=-TestName.*:TestName.*TestCase
Vijay C
źródło
4

W innym podejściu można opakować testy w funkcję i używać normalnych testów warunkowych w czasie wykonywania, aby wykonywać je tylko wtedy, gdy chcesz.

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

Jest to przydatne dla mnie, ponieważ próbuję uruchomić niektóre testy tylko wtedy, gdy system obsługuje protokół IPv6 z dwoma stosami.

Technicznie rzecz biorąc, te rzeczy z podwójnym stosem nie powinny być testem jednostkowym, ponieważ zależy to od systemu. Ale tak naprawdę nie mogę wykonać żadnych testów integracyjnych, dopóki nie sprawdzę, czy i tak działają, a to gwarantuje, że nie zgłosi awarii, gdy nie jest to błąd kodów.

Jeśli chodzi o test, to mam obiekty odgałęzione, które symulują obsługę systemu dla dualstack (lub jego brak), konstruując fałszywe gniazda.

Jedynym minusem jest to, że wynik testu i liczba testów ulegną zmianie, co może powodować problemy z czymś, co monitoruje liczbę udanych testów.

Możesz także użyć ASSERT_ * zamiast EQUAL_ *. Jeśli się nie powiedzie, zapewni pozostałą część testu. Zapobiega zrzucaniu wielu zbędnych rzeczy na konsolę.

David C. Bishop
źródło
4

Miałem taką samą potrzebę testów warunkowych i znalazłem dobre obejście. Zdefiniowałem makro TEST_C, które działa jak makro TEST_F, ale ma trzeci parametr, który jest wyrażeniem boolowskim, oszacowany runtime w main.cpp PRZED rozpoczęciem testów. Testy, które oceniają false, nie są wykonywane. Makro jest brzydkie, ale wygląda tak:

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

Dodatkowo w pliku main.cpp potrzebujesz tej pętli, aby wykluczyć testy, które oceniają false:

// 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
źródło
Jak zdefiniowałeś „filtr” w std :: string str = :: testing :: GTEST_FLAG (filter) ;?
beasone