2009-08-04 13 views
5

Mam kod gdzie assertRaises zgłasza wyjątek, gdy assertRaises kończy się niepowodzeniem. Pomyślałem, że jeśli asertRaises się nie powiedzie, test zakończy się niepowodzeniem i na końcu otrzymam raport, który mówi, że test się nie powiódł. Nie spodziewałem się, że wyjątek zostanie rzucony. Poniżej znajduje się mój kod. Robię coś złego? Używam Python 2.6.2.python unittest assertRaises wyrzuca wyjątek, gdy assertRaises kończy się niepowodzeniem

import unittest 

class myClass: 

    def getName(self): 

     raise myExcOne, "my exception one" 
     #raise myExcTwo, "my exception two" 
     #return "a" 

class myExcOne(Exception): 
    "exception one" 

class myExcTwo(Exception): 
    "exception two" 


class test_myClass(unittest.TestCase): 

    def setUp(self): 

     self.myClass = myClass() 

    def testgetNameEmpty(self): 
     #self.assertRaises(myExcOne,self.myClass.getName) 
     #self.assertRaises(myExcTwo,self.myClass.getName) 

     try: 
      self.assertRaises(myExcTwo,self.myClass.getName) 
     except Exception as e: 
      pass 

if __name__ == "__main__": 

    #unittest.main() 

    suite = unittest.TestLoader().loadTestsFromTestCase(test_myClass) 
    unittest.TextTestRunner(verbosity=2).run(suite) 
+0

co konkretnie rozumiesz przez "assert failed"? Czy możesz opublikować stacktrace lub komunikat o błędzie? –

+0

Ponownie odczytuję dokument i wyrzucam wyjątek, gdy assertRaises zawodzi, to oczekiwane zachowanie. Źle zrozumiałem, jak działa to narzędzie. Zapomniałem o tym wspomnieć w poprzednim poście. Jeśli wychwycę wyjątek, raport powie mi, że test minął, mimo że nie. Zaktualizowałem swój kod na –

Odpowiedz

6

Kod wysłany jest nieprawidłowy. Na początek, class myClass(): powinien być class myClass:. Również if name == "main": powinno być:

if __name__ == "__main__": 
    unittest.main() 

Oprócz tych problemów, to nie dlatego, getName() jest podnoszenie wyjątek myExcOne a badanie przewiduje wyjątek myExcTwo.

Oto kod, który działa. Proszę edytować kod w swoim pytaniu tak, że jest nam łatwo wyciąć i wkleić go do sesji Python:

import unittest 

class myExcOne(Exception): "exception one" 

class myExcTwo(Exception): "exception two" 

class myClass: 
    def getName(self): 
     raise myExcTwo 

class test_myClass(unittest.TestCase): 
    def setUp(self): 
     self.myClass = myClass() 
    def testgetNameEmpty(self): 
     #self.assertRaises(myExcOne,self.myClass.getName) 
     self.assertRaises(myExcTwo,self.myClass.getName) 

if __name__ == "__main__": 
    unittest.main() 
+0

Hi mhawke, __main__ został popsuty w procesie kopiowania i wklejania. Dla klasy myClass() oryginalna klasa odziedziczyła, więc zapomniałem usunąć(), gdy zrobiłem małą próbkę. Test powinien zakończyć się niepowodzeniem. Próbuję zrozumieć, jak zachowuje się narzędzie, gdy awaria zakończy się niepowodzeniem. Dla mojego oryginalnego posta, błędnie zrozumiałem, że narzędzie ma wyrzucać wyjątek, jeśli twierdzenie nie powiedzie się. Zaktualizowałem kod, aby wychwycić wyjątek i nic z nim nie zrobić. Nawet jeśli twierdzenie nie powiedzie się, raport mówi, że minął. Brian –

5

zaczynający się na bok, () po classname w class oświadczenia jest całkowicie poprawne w nowoczesny Python - wcale nie jest błędem.

Na mięsa emisji, assertRaises(MyException, foo) jest udokumentowana propagować wyjątki podniesione przez wywołanie foo() którego typ nie jest podklasą MyException - to tylko łapie MyException i ich podklas. Ponieważ kod generuje wyjątek od jednego typu, a test oczekuje od jednego z różnych niepowiązanych typów, podniesiony wyjątek będzie następnie propagowany, zgodnie z dokumentami modułu unittest, , i cytuję: "test przechodzi, jeśli zostanie zgłoszony wyjątek, jest błędem, jeśli zgłoszony jest inny wyjątek, lub nie powiedzie się, jeśli nie zostanie zgłoszony wyjątek "- i" jest błędem "oznacza" propaguje inny wyjątek ".

Podczas przechwytywania wyjątku propagującego w bloku try/except, anulujesz błąd i nie ma już nic do unittest do zdiagnozowania. Jeśli Twoim celem jest przekształcenie tego błędu w niepowodzenie (strategia dyskusyjna ...), twój blok except powinien wywołać self.fail.

+0

Dziękuję za pomoc! Nie zauważyłem mojego nieporozumienia na temat unieważnienia aż po tym, jak napisałem. Z powyższym kodem, jeśli go uruchomię, otrzymuję komunikat . Spodziewałbym się, że to się nie uda, ale zrozumiem, dlaczego przekazuje wiadomość. Kiedy dodałem self.fail w bloku except, generuje on inny wyjątek. Wszelkie sugestie, aby umożliwić uruchomienie wszystkich testów i zgłosić błędy na końcu? Znalazłem ale nie jestem pewien jak (lub jeśli mogę) uzyskać wyniki. –

+0

wszystkie metody testowania działają i zgłaszają błędy (E) i awarie (F) [które są zdiagnozowane przez specjalne wyjątki, faktycznie] z normalnym biegaczem testu jednostkowego (unittest.main) - jestem zaskoczony słysząc, że TextTestRunner zachowuje się inaczej dla ciebie, ponieważ jest to dokładnie to, czego używa unittest.main (przez klasę unittest.TestProgram), sprawdź źródła ... dostaniesz oczekiwane wyniki w/unittest.main, prawda? –

+0

Jeśli wyjmę próbę/except block i odkomentuję to mój debugger zatrzymuje wykonywanie. Uruchomiłem program z wiersza poleceń, uruchomiłem wszystkie testy i dałem oczekiwane rezultaty. Tego właśnie szukałem. Ale jeśli uruchomiłem kod, jak jest on wymieniony powyżej, mówi mi, że przechodzi, mimo że powinien zawieść. Nie martwię się tym, ponieważ uruchomienie testu urządzenia z wiersza poleceń daje mi to, czego chcę. Jeszcze raz dziękuję za pomoc. –

Powiązane problemy