GoogleTest: comment sauter un test?

121

Utilisation de Google Test 1.6 (Windows 7, Visual Studio C ++). Comment puis-je désactiver un test donné? (aka comment puis-je empêcher un test de s'exécuter). Puis-je faire autre chose que de commenter l'ensemble du test?

Utilisateur
la source

Réponses:

179

La documentation pour Google Test 1.7 suggère :

"Si vous avez un test défectueux que vous ne pouvez pas corriger tout de suite, vous pouvez ajouter le préfixe DISABLED_ à son nom. Cela l'exclura de l'exécution."

Exemples:

// 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) { ... }
Facture
la source
1
Je viens de le trouver aussi et filtre
Utilisateur
@Bill, je l'ai trouvé juste avant que vous ne postiez votre commentaire ... (et je l'ai également mis en place comme réponse). J'ai ensuite supprimé mon commentaire, pensant qu'il était obsolète ... mais ce sont de très bonnes informations! +1
Kiril
67

Vous pouvez également exécuter un sous-ensemble de tests , selon la documentation:

Exécution d'un sous-ensemble de tests

Par défaut, un programme de test Google exécute tous les tests définis par l'utilisateur. Parfois, vous souhaitez exécuter uniquement un sous-ensemble des tests (par exemple pour le débogage ou la vérification rapide d'un changement). Si vous définissez la variable d'environnement GTEST_FILTER ou l'indicateur --gtest_filter sur une chaîne de filtre, Google Test exécutera uniquement les tests dont les noms complets (sous la forme TestCaseName.TestName) correspondent au filtre.

Le format d'un filtre est une liste séparée par ':' de motifs génériques (appelés motifs positifs), éventuellement suivie d'un '-' et d'une autre liste de motifs séparés par ':' (appelés motifs négatifs). Un test correspond au filtre si et seulement s'il correspond à l'un des modèles positifs mais ne correspond à aucun des modèles négatifs.

Un modèle peut contenir '*' (correspond à n'importe quelle chaîne) ou '?' (correspond à n'importe quel caractère unique). Pour plus de commodité, le filtre '* -NegativePatterns' peut également être écrit sous la forme '-NegativePatterns'.

Par exemple:

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

Pas la plus jolie solution, mais ça marche.

Kiril
la source
24

Vous pouvez maintenant utiliser la GTEST_SKIP()macro pour ignorer conditionnellement un test lors de l'exécution. Par exemple:

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

    ...
}

Notez qu'il s'agit d'une fonctionnalité très récente , vous devrez peut-être mettre à jour votre bibliothèque GoogleTest pour l'utiliser.

Peter Bloomfield
la source
Cette fonctionnalité n'est pas encore disponible. Il est peu probable qu'il soit inclus dans une branche 1.8.x, car seuls les correctifs y sont acceptés. 1.9 n'est pas encore disponible, pas encore annoncé pour le moment.
ocroquette
2
GTEST_SKIP()est disponible à partir de la 1.10.0.
mattdibi
Malheureusement, la documentation est encore rare à ce sujet. Il semble qu'il y en ait aussi GTEST_SKIP_("some message")(notez le trait de soulignement de fin)
Matthäus Brandl
19

Voici l'expression pour inclure les tests dont les noms contiennent les chaînes foo1 ou foo2 et exclure les tests dont les noms contiennent les chaînes bar1 ou bar2:

--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*
ashutosh
la source
10

Je préfère le faire en 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

Je peux soit commenter les deux lignes pour exécuter tous les tests, décommenter la première ligne pour tester une seule fonctionnalité sur laquelle j'étudie / travaille, soit décommenter la deuxième ligne si un test est interrompu mais je veux tester tout le reste.
Vous pouvez également tester / exclure une suite de fonctionnalités en utilisant des caractères génériques et en écrivant une liste, "MyLibrary.TestNetwork *" ou "-MyLibrary.TestFileSystem *".

pilkch
la source
C'est une excellente solution. Je l'utilise pour exclure certains tests par défaut si le filtre est vide. Ils peuvent être activés avec export GTEST_FILTER='*'.
Timmmm
En fait, cela ne fonctionne pas car la valeur par défaut est " *" pas "". Au lieu de cela, je vais simplement utiliser une autre variable d'environnement qui remplace le filtre.
Timmmm
Où avez-vous défini le «filtre»? Est-ce une ficelle?
beasone
Je ne le définit pas donc je pense que ce doit être un global inclus de gtest / gtest.h?
pilkch
6

Si plus d'un test est nécessaire, sautez

--gtest_filter=-TestName.*:TestName.*TestCase
Vijay C
la source
5

Pour une autre approche, vous pouvez encapsuler vos tests dans une fonction et utiliser des vérifications conditionnelles normales à l'exécution pour les exécuter uniquement si vous le souhaitez.

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

Ceci est utile pour moi car j'essaie d'exécuter certains tests uniquement lorsqu'un système prend en charge IPv6 double pile.

Techniquement, ce truc dualstack ne devrait pas vraiment être un test unitaire car cela dépend du système. Mais je ne peux pas vraiment faire de tests d'intégration tant que je n'ai pas testé qu'ils fonctionnent de toute façon et cela garantit qu'il ne signalera pas les échecs quand ce n'est pas la faute des codes.

En ce qui concerne le test, j'ai des objets stub qui simulent la prise en charge par un système de la double pile (ou l'absence de) en construisant de fausses sockets.

Le seul inconvénient est que la sortie du test et le nombre de tests changeront, ce qui pourrait entraîner des problèmes avec quelque chose qui surveille le nombre de tests réussis.

Vous pouvez également utiliser ASSERT_ * plutôt que EQUAL_ *. Assert will about le reste du test s'il échoue. Empêche un grand nombre de choses redondantes d'être vidées sur la console.

David C. Bishop
la source
4

J'avais le même besoin de tests conditionnels et j'ai trouvé une bonne solution de contournement. J'ai défini une macro TEST_C qui fonctionne comme une macro TEST_F, mais elle a un troisième paramètre, qui est une expression booléenne, évalué à l'exécution dans main.cpp AVANT le démarrage des tests. Les tests qui évaluent faux ne sont pas exécutés. La macro est moche, mais elle ressemble à:

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

De plus, dans votre main.cpp, vous avez besoin de cette boucle pour exclure les tests qui évaluent 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
la source
Comment avez-vous défini "filtre" dans std :: string str = :: testing :: GTEST_FLAG (filtre) ;?
beasone