2009-08-04 5 views
5

Ho il codice in cui assertRaises genera un'eccezione quando AssertRaises fallisce. Ho pensato che se assertRaises fallisse, il test fallirebbe e alla fine avrò un rapporto che dice che il test fallisce. Non mi aspettavo che l'eccezione venisse lanciata. Di seguito è il mio codice. Sto facendo qualcosa di sbagliato? Sto usando Python 2.6.2.python unittest assertRaises genera un'eccezione quando assertRaises fallisce

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

cosa intendete per "asserire fallito"? Puoi pubblicare uno stacktrace o un messaggio di errore? –

+0

Rileggo il documento e lancio un'eccezione quando assertRaises non riesce è il comportamento previsto. Ho frainteso come funziona lo strumento. Ho dimenticato di dirlo nel post precedente. Se rilevo l'eccezione, il rapporto mi dice che il test è stato superato anche se non lo è stato. Ho aggiornato il mio codice su –

risposta

6

Il codice inviato non è corretto. Per cominciare, class myClass(): shoudl essere class myClass:. Anche if name == "main": dovrebbe essere:

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

Oltre a questi problemi, questo fallisce perché getName() sta sollevando un'eccezione myExcOne e il test prevede un'eccezione myExcTwo.

Ecco un codice che funziona. Si prega di modificare il codice nella tua domanda in modo che sia facile per noi di tagliare e incollare in una sessione di 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, Il __main__ è incasinato nel processo di copia e incolla. Per myClass(), la classe originale è stata ereditata, quindi ho dimenticato di eliminare() quando ho creato il piccolo testcase. Il test dovrebbe fallire. Sto cercando di capire come si comporta lo strumento quando un assert fallisce. Per il mio post originale, ho frainteso che lo strumento dovrebbe generare un'eccezione se un assert non riesce. Ho aggiornato il codice per rilevare l'eccezione e non fare nulla con esso. Anche se l'affermazione fallisce, il rapporto dice che è passato. Brian –

5

Partendo da un parte, il () dopo il nome di classe in un comunicato class è perfettamente corretto nella moderna Python - non è un errore.

sulla carne della questione, assertRaises(MyException, foo) è documentato per propagare eccezioni sollevate chiamando foo() il cui tipo non è una sottoclasse di MyException - cattura solo MyException e sottoclassi della stessa. Poiché il tuo codice solleva un'eccezione di un tipo e il tuo test si aspetta uno di un diverso tipo non correlato, l'eccezione sollevata verrà propagata, come per i documenti del modulo unittest, here e cito: "il test passa se viene sollevata un'eccezione, è un errore se viene sollevata un'altra eccezione, oppure fallisce se non viene sollevata alcuna eccezione "- e" è un errore "significa" propaga l'altra eccezione ".

Mentre si rilevano le eccezioni che si propagano nel blocco try/except, si annulla l'errore e non è rimasto nulla per l'unittest da diagnosticare. Se il tuo scopo è trasformare questo errore in un errore (una strategia discutibile ...), il tuo blocco except dovrebbe chiamare self.fail.

+0

Grazie per il vostro aiuto !!! Non ho capito il mio malinteso di unittest fino a dopo aver postato. Con il codice sopra se lo eseguo, ricevo il messaggio . Mi aspetterei che fallisse, ma capisco perché dà il messaggio. Quando ho aggiunto self.fail nel blocco tranne che getta un'altra eccezione. Qualche suggerimento per consentire l'esecuzione di tutti i test e segnalare gli errori alla fine? Ho trovato ma non sono sicuro di come (o se posso) ottenere i risultati. –

+0

tutti i metodi di test DO eseguono e riportano errori (E) e guasti (F) [che sono diagnosticati da eccezioni speciali, in realtà] con il normale unit-test runner (unittest.main) - Sono sorpreso di sentire che TextTestRunner si comporta in modo diverso per te, dato che questo è esattamente ciò che unittest.main usa (tramite la classe unittest.TestProgram), controlla le fonti ... ottieni i risultati attesi con unittest.main, giusto? –

+0

Se eseguo il try/except block e uncomment allora è il mio debugger che sta fermando l'esecuzione. Ho eseguito il programma da una riga di comando, ha eseguito tutti i test e fornito i risultati che mi aspetto. Questo è quello che stavo cercando. Ma se ho eseguito il codice come è elencato sopra, mi dice che passa anche se dovrebbe fallire. Non mi preoccupo di questo dato che eseguire il test unitario dalla riga di comando mi dà quello che voglio. Grazie ancora per il tuo aiuto. –