Kann ein Komponententest bestätigen, dass eine Methode sys.exit () aufruft?

98

Ich habe eine Python 2.7-Methode, die manchmal aufruft

sys.exit(1) 

Ist es möglich, einen Komponententest durchzuführen, der bestätigt, dass diese Codezeile aufgerufen wird, wenn die richtigen Bedingungen erfüllt sind?

Travis Bär
quelle

Antworten:

154

Ja. sys.exiterhöht SystemExit, so können Sie es überprüfen mit assertRaises:

with self.assertRaises(SystemExit):
    your_method()

Instanzen von SystemExithaben ein Attribut, codedas auf den vorgeschlagenen Beendigungsstatus festgelegt ist, und der von zurückgegebene Kontextmanager assertRaiseshat die abgefangene Ausnahmeinstanz als exception, sodass das Überprüfen des Beendigungsstatus einfach ist:

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

sys.exit Dokumentation :

Beenden Sie Python. Dies wird durch Auslösen der SystemExitAusnahme implementiert. Es ist möglich, den Exit-Versuch auf einer äußeren Ebene abzufangen.

Pavel Anossov
quelle
3
+1, außer dass, wenn er überprüfen möchte, ob es anruft sys.exit(1)(im Gegensatz zu beispielsweise sys.exit(0)), Sie tatsächlich behaupten müssen, dass codees 1 ist. Ich denke, Sie könnten das mit tun assertRaisesRegexp(SystemExit, '1')?
abarnert
Ich war mir sicher, dass es eine unittestMethode gibt, mit der Sie eine Ausnahme und ein aufrufbares Prädikat übergeben können , um die Ausnahme oder ihre Argumente auszuführen, und nicht nur ein Regex-Muster , das für die Zeichenfolgendarstellung des ersten Arguments ausgeführt werden soll… aber ich denke nicht. Gibt es ein anderes Testmodul, an das ich denke?
abarnert
1
+1, was das Überprüfen von Fehlercode betrifft, ist es viel einfacher, nur Folgendes zu tun: self.assertRaisesRegex( SystemExit, '^2$', testMethod ) Weniger Code, lesbar genug.
Marek Lewandowski
1
@MarekLewandowski - Tippfehler. Muss seinself.assertRaisesRegexp
Evgen
12

Hier ist ein vollständiges Arbeitsbeispiel. Trotz Pavel's hervorragender Antwort habe ich eine Weile gebraucht, um das herauszufinden, also nehme ich es hier in der Hoffnung auf, dass es hilfreich sein wird.

import unittest
from glf.logtype.grinder.mapping_reader import MapReader

INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"

class TestMapReader(unittest.TestCase):

    def test_get_tx_names_incomplete_mapping_file(self):
        map_reader = MapReader()
        with self.assertRaises(SystemExit) as cm:
            tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
        self.assertEqual(cm.exception.code, 1)
Travis Bär
quelle
3

Ich habe die Antwort auf Ihre Frage in der Python Unit Testing-Dokumentationssuche nach "Testen auf Ausnahmen" gefunden. Anhand Ihres Beispiels würde der Komponententest folgendermaßen aussehen:

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

Denken Sie daran, alle Argumente anzugeben, die zum Testen Ihrer Funktion erforderlich sind.

Sleepykyle
quelle
1

Als zusätzlichen Hinweis zu Pavel's hervorragender Antwort können Sie auch nach bestimmten Status suchen, wenn diese in der von Ihnen getesteten Funktion bereitgestellt werden. Wenn zum Beispiel your_method()Folgendes enthalten sys.exit("Error")wäre, wäre es möglich, speziell auf "Fehler" zu testen:

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")
binäres Substrat
quelle