GoogleTest: come saltare un test?


119

Utilizzando Google Test 1.6 (Windows 7, Visual Studio C ++). Come posso disattivare un determinato test? (aka come posso impedire l'esecuzione di un test). C'è qualcosa che posso fare oltre a commentare l'intero test?

Risposte:


178

I documenti per Google Test 1.7 suggeriscono :

"Se hai un test non funzionante che non puoi correggere subito, puoi aggiungere il prefisso DISABLED_ al suo nome. Questo lo escluderà dall'esecuzione."

Esempi:

// 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) { ... }

1
l'ho appena trovato anch'io e filtri
Utente

@ Bill, l'ho trovato poco prima che scrivessi il tuo commento ... (e l'ho messo anche io come risposta). Ho quindi rimosso il mio commento, immaginando che fosse obsoleto ... ma sono davvero buone informazioni! +1
Kiril

67

Puoi anche eseguire un sottoinsieme di test , secondo la documentazione:

Esecuzione di un sottoinsieme dei test

Per impostazione predefinita, un programma di test di Google esegue tutti i test definiti dall'utente. A volte, si desidera eseguire solo un sottoinsieme dei test (ad esempio per eseguire il debug o verificare rapidamente una modifica). Se imposti la variabile d'ambiente GTEST_FILTER o il flag --gtest_filter su una stringa di filtro, Google Test eseguirà solo i test i cui nomi completi (sotto forma di TestCaseName.TestName) corrispondono al filtro.

Il formato di un filtro è un elenco separato da ":" di caratteri jolly (chiamati modelli positivi) seguito facoltativamente da un "-" e da un altro elenco di modelli separati da ":" (chiamati modelli negativi). Un test corrisponde al filtro se e solo se corrisponde a uno qualsiasi dei modelli positivi ma non corrisponde a nessuno dei modelli negativi.

Un modello può contenere "*" (corrisponde a qualsiasi stringa) o "?" (corrisponde a qualsiasi singolo carattere). Per comodità, il filtro "* -NegativePatterns" può anche essere scritto come "-NegativePatterns".

Per esempio:

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

Non è la soluzione più carina, ma funziona.


24

È ora possibile utilizzare la GTEST_SKIP()macro per saltare in modo condizionale un test in fase di esecuzione. Per esempio:

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

    ...
}

Tieni presente che questa è una funzionalità molto recente, quindi potrebbe essere necessario aggiornare la libreria di GoogleTest per utilizzarla.


Questa funzione non è ancora stata rilasciata. È improbabile che venga incluso in un ramo 1.8.x, poiché lì sono accettate solo le correzioni. 1.9 non è ancora disponibile, nemmeno annunciato in questo momento.
ocroquette

2
GTEST_SKIP()è disponibile dalla 1.10.0.
mattdibi

Purtroppo la documentazione è ancora scarsa intorno a questo. Sembra che ci sia anche GTEST_SKIP_("some message")(nota la sottolineatura finale)
Matthäus Brandl il

19

Ecco l'espressione per includere i test i cui nomi contengono le stringhe foo1 o foo2 ed escludere i test i cui nomi contengono le stringhe bar1 o bar2:

--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*

10

Preferisco farlo in codice:

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

Posso commentare entrambe le righe per eseguire tutti i test, decommentare la prima riga per testare una singola funzionalità su cui sto indagando / lavorando, o decommentare la seconda riga se un test è rotto ma voglio testare tutto il resto.
È inoltre possibile testare / escludere una suite di funzionalità utilizzando caratteri jolly e scrivendo un elenco, "MyLibrary.TestNetwork *" o "-MyLibrary.TestFileSystem *".


Questa è un'ottima soluzione. Lo uso per escludere alcuni test di default se il filtro è vuoto. Possono essere abilitati con export GTEST_FILTER='*'.
Timmmm

In realtà non funziona perché l'impostazione predefinita è " *" non "". Invece userò solo un'altra variabile d'ambiente che sovrascrive il filtro.
Timmmm

Dove hai definito il "filtro"? È una stringa?
beasone

Non lo definisco quindi penso che debba essere un globale incluso da gtest / gtest.h?
pilkch

6

Se è necessario più di un test, saltare

--gtest_filter=-TestName.*:TestName.*TestCase

5

Per un altro approccio, puoi racchiudere i tuoi test in una funzione e utilizzare i normali controlli condizionali in fase di esecuzione per eseguirli solo se lo desideri.

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

Questo è utile per me poiché sto cercando di eseguire alcuni test solo quando un sistema supporta IPv6 dual stack.

Tecnicamente quella roba dualstack non dovrebbe davvero essere uno unit test in quanto dipende dal sistema. Ma non posso davvero fare alcun test di integrazione finché non ho testato che funzionano comunque e questo garantisce che non segnalerà errori quando non è l'errore dei codici.

Per quanto riguarda il test, ho oggetti stub che simulano il supporto di un sistema per il dualstack (o la mancanza di) costruendo falsi socket.

L'unico svantaggio è che l'output del test e il numero di test cambieranno, il che potrebbe causare problemi con qualcosa che monitora il numero di test riusciti.

Puoi anche utilizzare ASSERT_ * anziché EQUAL_ *. Affermare la volontà sul resto del test se fallisce. Impedisce che molte cose ridondanti vengano scaricate sulla console.


4

Avevo la stessa necessità di test condizionali e ho trovato una buona soluzione alternativa. Ho definito una macro TEST_C che funziona come una macro TEST_F, ma ha un terzo parametro, che è un'espressione booleana, runtime valutato in main.cpp PRIMA che i test vengano avviati. I test che valutano false non vengono eseguiti. La macro è brutta, ma assomiglia a:

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

Inoltre, nel tuo main.cpp, hai bisogno di questo ciclo per escludere i test che valutano 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();

Come hai definito "filtro" in std :: string str = :: testing :: GTEST_FLAG (filtro) ;?
beasone
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.