2017-10-03 6 views
2

J'ai un test d'intégration qui est quelque chose comme:Comment puis-je vérifier combien de `EXPECT_ *` appels a échoué lors d'un test

TEST(foo, test_many_foos) { 
    foo_builder sut; 
    sut.set_some_params(); 

    sut.run(); 

    for (const auto foo : sut) { 
     EXPECT_TRUE(some_check(foo)); 
    } 


    // TODO: Print a summary of how many EXPECT_TRUEs failed 

} 

Est-il possible que je peux imprimer un résumé des résultats de tous les appels EXPECT à la fin du test?

+1

N'est-ce pas l'arrêt après la première panne? Nwm, c'est la famille de macros 'ASSERT_ *' qui arrête les tests tôt. En fait, selon les docs, chaque appel attendu ajoutera un nouveau message d'échec lorsque la condition est fausse. – VTT

+0

Expect permet au test de continuer plutôt que de l'arrêter dans ses pistes. Dans mon cas, je génère environ 200 000 'foo's et environ 50 d'entre eux échouent. C'est trop de compter facilement en les regardant à l'œil nu. Je voudrais un message à la fin disant "X échecs EXPECT" ou quelque chose comme ça –

Répondre

1

Une solution que je suis venu avec (que je ne suis pas entièrement satisfait) est de faire ce qui suit:

class stream_counter 
{ 
public: 
    explicit stream_counter(int *val) : val_(val) {} 
    void       increment_count() const { ++*val_; } 

private: 
    int *val_; 
}; 

std::ostream &operator<<(std::ostream &os, const stream_counter &sc) 
{ 
    sc.increment_count(); 
    return os; 
} 

TEST(foo, test_many_foos) { 
    foo_builder sut; 
    sut.set_some_params(); 

    sut.run(); 

    int n_failures = 0; 

    for (const auto foo : sut) { 
     EXPECT_TRUE(some_check(foo)) << stream_counter{&n_failures}; 
    } 

    if(n_failures > 0) { 
     std::cout << "There were " << n_failures << " failures" << std::endl; 
    } 

} 

Ce abus le comportement operator << IOF EXPECT_* qui permettent l'impression d'un message au flux d'erreur si la vérification échoue. stream_counter enveloppe simplement un nombre entier et l'incrémente si l'objet est diffusé sur un std::ostream

Pas la solution la plus propre, mais elle fait ce que je veux.

+0

Vous pourriez éliminer cette classe supplémentaire avec un lambda: https://gist.github.com/LegalizeAdulthood/179f4ff9b1bc48e380478d1e0138ae4a – legalize

1
TEST(foo, test_many_foos) { 
    foo_builder sut; 
    sut.set_some_params(); 

    sut.run(); 

    auto n_failures = 0; 
    for (const auto foo : sut) { 
     auto const result = some_check(foo); 
     EXPECT_TRUE(result); 
     if (!result) ++n_failures; 
    } 

    if(n_failures > 0) { 
     std::cout << "There were " << n_failures << " failures" << std::endl; 
    } 
} 

Ceci, cependant, signifie que EXPECT_TRUE() affichera quelque chose à propos de "result" plutôt que "some_check (foo)".

1

Vous pouvez améliorer Google Test en utilisant un custom event listener. Vous pouvez définir votre propre classe d'auditeur et l'ont suivi le nombre de fois qu'un EXPECT_*() appel échoue par test:

class ExpectListener : public ::testing::EmptyTestEventListener { 
    int nFailures; 

    // Called before a test starts. 
    virtual void OnTestStart(const ::testing::TestInfo& test_info) { 
     nFailures = 0; 

     printf("*** Test %s.%s starting.\n", 
       test_info.test_case_name(), 
       test_info.name()); 
    } 

    // Called after a failed assertion or a SUCCEED() invocation. 
    virtual void OnTestPartResult(const ::testing::TestPartResult& test_part_result) { 
     if (test_part_result.nonfatally_failed()) {nFailures++;} 

     printf("%s in %s:%d\n%s\n", 
       test_part_result.failed() ? "*** Failure" : "Success", 
       test_part_result.file_name(), 
       test_part_result.line_number(), 
       test_part_result.summary()); 
    } 

    // Called after a test ends. 
    virtual void OnTestEnd(const ::testing::TestInfo& test_info) { 
     printf("*** Test %s.%s ending with %d failures.\n", 
       test_info.test_case_name(), 
       test_info.name(), 
       nFailures); 
    } 
}; 

Maintenant, il suffit de remplacer l'auditeur par défaut de Google Test avec cet écouteur personnalisé:

int main(int argc, char** argv) { 
    ::testing::InitGoogleTest(&argc, argv); 

    ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); 
    delete listeners.Release(listeners.default_result_printer()); 
    listeners.Append(new ExpectListener); 

    return RUN_ALL_TESTS(); 
} 

Vous ne besoin de mettre en place une fois (en main()); tous les tests suivront ensuite le nombre de défaillances non fatales qu'ils ont subies. Bien sûr, vous pouvez personnaliser davantage cet écouteur si vous souhaitez modifier les messages de test ou suivre plus d'informations.