Czy test jednostkowy może potwierdzić, że metoda wywołuje sys.exit ()

Odpowiedzi:

155

Tak. sys.exitpodbija SystemExit, więc możesz to sprawdzić assertRaises:

with self.assertRaises(SystemExit):
    your_method()

Instancje SystemExitmają atrybut, codektóry jest ustawiony na proponowany status wyjścia, a menedżer kontekstu zwrócony przez assertRaisesma przechwyconą instancję wyjątku jako exception, więc sprawdzenie statusu wyjścia jest łatwe:

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

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

 

sys.exit Dokumentacja :

Wyjdź z Pythona. Jest to realizowane poprzez podniesienie SystemExitwyjątku ... możliwe jest przechwycenie próby wyjścia na poziomie zewnętrznym.

Pavel Anossov
źródło
3
+1, z wyjątkiem tego, że jeśli chce sprawdzić, czy wywołuje sys.exit(1)(w przeciwieństwie do, powiedzmy, sys.exit(0)), musisz potwierdzić, że jego codewynosi 1. Myślę, że mógłbyś to zrobić z assertRaisesRegexp(SystemExit, '1')?
abarnert
Byłem pewien, że istnieje unittestmetoda, która pozwala przekazać wyjątek i wywoływalny predykat do uruchomienia na wyjątku lub jego argumentach, zamiast po prostu wzorca regex do uruchomienia na łańcuchowej reprezentacji jego pierwszego argumentu… ale myślę, że nie. Czy myślę o jakimś innym module testowym?
abarnert
1
+1, jeśli chodzi o sprawdzenie kodu błędu, jest to o wiele prostsze do zrobienia: self.assertRaisesRegex( SystemExit, '^2$', testMethod ) mniej kodu, wystarczająco czytelny.
Marek Lewandowski
1
@MarekLewandowski - literówka. Musi byćself.assertRaisesRegexp
Evgen
12

Oto kompletny przykład roboczy. Pomimo doskonałej odpowiedzi Pavla zajęło mi trochę czasu, zanim to rozgryzłem, więc dołączam ją tutaj w nadziei, że okaże się pomocna.

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 Bear
źródło
3

Znalazłem odpowiedź na twoje pytanie w dokumentacji Python Unit Testing, wyszukując hasło „Testing for Exceptions”. Na Twoim przykładzie test jednostkowy wyglądałby następująco:

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

Pamiętaj, aby uwzględnić wszystkie argumenty potrzebne do przetestowania Twojej funkcji.

sleepykyle
źródło
1

Jako dodatkowa uwaga do doskonałej odpowiedzi Pawła, możesz również sprawdzić określone statusy, jeśli są one dostępne w testowanej funkcji. Na przykład, gdyby your_method()zawierał następujące elementy sys.exit("Error"), można by przetestować konkretnie pod kątem „błędu”:

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")
binarysubstrate
źródło