2016-08-30 2 views
6

Ich benutze gtest, um einige Komponententests für Ausnahmebehandlungscode zu schreiben. Als einfaches Beispiel, sagen wir, ich mein Programm auf jede nicht behandelte Ausnahme abort wollen, so dass ich erstellen Sie den folgenden Test:schreibe den Todtest, um das std :: set_terminate-Verhalten zu verifizieren

TEST_F(myFixture, myTest) 
{ 
    std::set_terminate([](){std::abort(); }); 

    EXPECT_DEATH(throw std::runtime_error("terminate"), ".*"); 
} 

Ich würde dies, um erfolgreich zu sein erwarten, da abort auf dem Programm aufgerufen werden soll. Mein aktuelles Ergebnis ist jedoch:

error: Death test: throw std::runtime_error("terminate")

Result: threw an exception.
Error msg:

[ DEATH ]
[ DEATH ] main.cpp(122):: Caught std::exception-derived exception escaping the death test statement. Exception message: terminate

[ DEATH ]

Ich denke, dass gtests Ausnahme-Handler in die Quere kommen. Ich habe versucht, sie mit der Umgebungsvariablen GTEST_CATCH_EXCEPTIONS zu deaktivieren, und die --gtest_catch_exceptions=0 Befehlszeilenflagge wie in the advanced guide erwähnt, aber ich bekomme das gleiche Ergebnis.

Mache ich etwas falsch, oder ist "Tod durch Ausnahme" nicht etwas, für das gtest testen kann?

Antwort

5

Am I doing something wrong, or is "death by exception" not something gtest can test for?

Was Sie tun, ist falsch, weil „Tod durch Ausnahme“ nicht etwas ist Gtest für testen.

EXPECT_DEATH(statement, regex); 

überprüft, ob Anrufe statementabort oder exit und verursacht Ausgang regex entsprechen. Die Anweisung throw std::runtime_error("terminate") ruft abort oder 10 nicht auf, wie aus der Möglichkeit ersichtlich ist, irgendeine Ausnahme im Programm zu finden und weiterlaufen zu lassen. Wenn eine Ausnahme nicht abgefangen wird, ruft die Laufzeitbibliothek terminate auf und beendet das Programm auf die eine oder andere Weise. Aber dieses Ergebnis wird durch keine throw Anweisung bestimmt.

Siehe documentation of death-tests, insbesondere:

...any test that checks that a program terminates (except by throwing an exception) in an expected fashion is also a death test.

Note that if a piece of code throws an exception, we don't consider it "death" for the purpose of death tests, as the caller of the code could catch the exception and avoid the crash. If you want to verify exceptions thrown by your code, see Exception Assertions.

und:

Note that a death test only cares about three things:

  1. does statement abort or exit the process? ...

Ich schätze Sie Ihre eigentliche Frage sei hier oversimplfying aber Sie kaum, dass nicht behandelte Ausnahmen zu testen benötigen führen in terminate aufgerufen wird, oder dass terminate den operativen Terminator aufrufen, es sei denn es ist Ihre entmutigende Pflicht, die Implementierung von Ihren Compiler und Standard-Bibliothek zu testen. Vielleicht sollte mehr von dem wirklichen Problem ausgestrahlt werden?

Später

my problem with this is my program doesn't (or shouldn't) carry on. It should abort via the termination handler.

Es soll aber pro Dokumentation der Erwartung, dass Ihr Programm sollte nicht auf trägt durchEXPECT_DEATHauf jedethrowAussage nicht getestet, weil keine throw Aussage beendet das Programm.

What I really want to test is that the behavior of my set_terminate handler is correct.

Das Verhalten Ihres set_terminate Handler ist korrekt, wenn jeder nur dann, wenn dass Handler gesetzt zu haben, ein Aufruf an std::terminate() hat das Ergebnis Sie erwarten . Diese Frage ist unabhängig von jeder throw Aussage und es Ihnen gefällt können testen:

#include <iostream> 
#include <gtest/gtest.h> 
#include <exception> 


TEST(the_end, is_nigh) 
{ 
    std::set_terminate([](){std::cout << "Goodbye cruel world\n", std::abort(); }); 

    EXPECT_DEATH(std::terminate(), ".*"); 
} 
int main(int argc, char **argv) { 
    ::testing::InitGoogleTest(&argc, argv); 
    return RUN_ALL_TESTS(); 
} 

, die produziert:

[==========] Running 1 test from 1 test case. 
[----------] Global test environment set-up. 
[----------] 1 test from the_end 
[ RUN  ] the_end.is_nigh 
Goodbye cruel world 
[  OK ] the_end.is_nigh (172 ms) 
[----------] 1 test from the_end (172 ms total) 

[----------] Global test environment tear-down 
[==========] 1 test from 1 test case ran. (172 ms total) 
[ PASSED ] 1 test. 
+0

Was ich will wirklich testen, ist, dass das Verhalten meiner 'set_terminate' Handler korrekt ist und dass es aufgerufen wird, wenn ich denke, dass es sein sollte. Im realen Programm macht es mehrere Dinge (erzeugt Zeitstempel/Stack-Traces), bevor es schließlich 'abort' aufruft. –

+0

"wie aus der Möglichkeit hervorgeht, irgendeine Ausnahme im Programm zu finden und weiterlaufen zu lassen" ... mein Problem damit ist, dass mein Programm nicht weiterläuft (oder nicht). Es sollte über den Beendigungshandler "abgebrochen" werden. –

+0

@NicolasHolthaus Aktualisiert in diesem Licht. –

Verwandte Themen