Jak napisać unittest, który zawiedzie tylko wtedy, gdy funkcja nie zgłosi oczekiwanego wyjątku?
python
unit-testing
exception
exception-handling
Daryl Spitzer
źródło
źródło
myfunc
, musisz dodać je jako argumenty do wywołania assertRaises. Zobacz odpowiedź Daryla Spitzera.self.assertRaises(TypeError, mymod.myfunc)
. Pełną listę wbudowanych wyjątków można znaleźć tutaj: docs.python.org/3/library/exceptions.html#bltin-exceptionsself.assertRaises(SomeCoolException, Constructor, arg1)
Od wersji Python 2.7 można użyć menedżera kontekstu, aby uzyskać dostęp do rzuconego obiektu wyjątku:
http://docs.python.org/dev/library/unittest.html#unittest.TestCase.assertRaises
W Pythonie 3.5 musisz się owinąć,
context.exception
wstr
przeciwnym razie dostanieszTypeError
źródło
context.exception
nie przekazuje wiadomości; to jest typ.import unittest2
, musisz użyćstr()
, tjself.assertTrue('This is broken' in str(context.exception))
.Kod w mojej poprzedniej odpowiedzi można uprościć do:
A jeśli funkcja pobiera argumenty, po prostu przekaż je do assertRaises w następujący sposób:
źródło
2.7.15
. Jeśliafunction
inself.assertRaises(ExpectedException, afunction, arg1, arg2)
jest inicjatorem klasy, musisz podaćself
jako pierwszy argument, np.self.assertRaises(ExpectedException, Class, self, arg1, arg2)
Krótka odpowiedź:
Użyj
self.assertRaises
metody jako menedżera kontekstu:Demonstracja
Podejście oparte na najlepszych praktykach jest dość łatwe do wykazania w powłoce Pythona.
unittest
bibliotekiW Python 2.7 lub 3:
W Pythonie 2.6 możesz zainstalować backport
unittest
biblioteki 2.7 , o nazwie unittest2 , i po prostu alias, któryunittest
:Przykładowe testy
Teraz wklej do powłoki Pythona następujący test bezpieczeństwa typu Pythona:
Test używany jest
assertRaises
jako menedżer kontekstu, który zapewnia, że błąd jest odpowiednio wychwytywany i usuwany podczas rejestrowania.Możemy to również napisać bez menedżera kontekstu, patrz test drugi. Pierwszym argumentem byłby typ błędu, którego się spodziewasz, drugim argumentem, testowana funkcja, a pozostałe argumenty i słowa kluczowe args zostaną przekazane do tej funkcji.
Myślę, że korzystanie z menedżera kontekstu jest znacznie prostsze, czytelniejsze i łatwiejsze w utrzymaniu.
Przeprowadzanie testów
Aby uruchomić testy:
W Pythonie 2.6 prawdopodobnie potrzebujesz :
Twój terminal powinien wypisać następujące dane:
I widzimy to, jak się spodziewamy, próbując dodać a
1
i'1'
wynik wTypeError
.Aby uzyskać bardziej szczegółowe dane wyjściowe, spróbuj tego:
źródło
Twój kod powinien być zgodny z tym wzorcem (jest to najszczerszy test stylu modułu):
W Pythonie <2.7 ta konstrukcja jest przydatna do sprawdzania określonych wartości w oczekiwanym wyjątku. Unittest funkcja
assertRaises
sprawdza tylko, czy zgłoszony został wyjątek.źródło
assertRaises
, otrzymasz BŁĄD zamiast AWARII.od: http://www.lengrand.fr/2011/12/pythonunittest-assertraises-raises-error/
Po pierwsze, tutaj jest odpowiednia funkcja (wciąż dum: p) w pliku dum_function.py:
Oto test, który należy wykonać (wstawiony jest tylko ten test):
Jesteśmy teraz gotowi do przetestowania naszej funkcji! Oto, co dzieje się podczas próby uruchomienia testu:
Błąd TypeError został zgłoszony i generuje błąd testu. Problem polega na tym, że właśnie takiego zachowania chcieliśmy: s.
Aby uniknąć tego błędu, po prostu uruchom funkcję za pomocą lambda w wywołaniu testowym:
Ostateczny wynik:
Doskonały !
... i dla mnie też jest idealny !!
Dziękuję bardzo, panie Julien Lengrand-Lambert
Ten test faktycznie zwraca fałszywie dodatni . Dzieje się tak, ponieważ lambda wewnątrz „assertRaises” to jednostka, która podnosi błąd typu, a nie testowana funkcja.
źródło
self.assertRaises(TypeError, df.square_value(self.false_int))
wywołuje metodę i zwraca wynik. To, czego chcesz, to przekazać metodę i wszelkie argumenty i niech najgorsi mogą ją nazwać:self.assertRaises(TypeError, df.square_value, self.false_int)
Możesz zbudować własny,
contextmanager
aby sprawdzić, czy wyjątek został zgłoszony.A potem możesz użyć w
raises
ten sposób:Jeśli używasz
pytest
, ta rzecz jest już zaimplementowana. Możesz zrobićpytest.raises(Exception)
:Przykład:
A wynik:
źródło
unittest
modułu!Korzystam z doctest [1] prawie wszędzie, ponieważ podoba mi się to, że jednocześnie dokumentuję i testuję swoje funkcje.
Spójrz na ten kod:
Jeśli umieścisz ten przykład w module i uruchomisz go z wiersza poleceń, oba przypadki testowe zostaną ocenione i sprawdzone.
[1] Dokumentacja w języku Python: 23.2 doctest - Testuj interaktywne przykłady w języku Python
źródło
Właśnie odkryłem, że biblioteka Mock udostępnia metodę assertRaisesWithMessage () (w jej podklasie unittest.TestCase), która sprawdzi nie tylko, czy zgłoszony został oczekiwany wyjątek, ale również zgłoszony komunikat:
źródło
Tutaj jest wiele odpowiedzi. Kod pokazuje, w jaki sposób możemy stworzyć wyjątek, jak możemy wykorzystać ten wyjątek w naszych metodach, a na koniec, w jaki sposób można zweryfikować w teście jednostkowym, czy zgłaszane są poprawne wyjątki.
źródło
Możesz użyć assertRaises z najbardziej nieprzystosowanego modułu
źródło
Chociaż wszystkie odpowiedzi są w porządku, szukałem sposobu na sprawdzenie, czy funkcja zgłosiła wyjątek bez polegania na strukturach testów jednostkowych i konieczności pisania klas testowych.
Skończyło się na tym, że napisałem:
I nie powiedzie się na właściwej linii:
źródło