2015-06-04 31 views
7

Quando usi la libreria unittest da python 3 Vorrei fare alcune azioni solo se un test fallisce (ma questo dovrebbe essere a livello di classe quindi non devo scriverlo per ogni test). Ad esempio quando si utilizza si comportano c'era qualcosa come:Python unittest, fai qualcosa solo se il test fallisce

def after_step(context, step): 
    if step.status == "failed": 
     ... 

C'è qualcosa di simile per la libreria unittest e se no, quale sarebbe il metodo più semplice per fare qualcosa di simile?

+0

possibile duplicato del [Ottenere risultati unittest del Python in un metodo tearDown()] (http://stackoverflow.com/questions/4414234/getting-pythons-unittest-results-in-a-teardown-method) – ronakg

+1

Per chiunque abbia ancora questo problema, negli ultimi 2 anni ho utilizzato il suggerimento qui menzionato e funziona perfettamente: https://stackoverflow.com/a/23176373/2535477 – skamsie

risposta

0

Si potrebbe provare a farlo con decoratore:

class ExceptionHandler(object): 
def __init__(self, f): 
    self.f = f 

def __call__(self, *args, **kwargs): 
    try: 
     self.f(*args, **kwargs) 
    except: 
     print('do smth') 

E in prova di unità:

@ExceptionHandler 
def test_fail(self): 
    self.assert_false(True) 
2

che sto cercando di fare qualcosa di simile di recente e ho trovato una via d'uscita:

import unittest 

class MyTestResult(unittest.TestResult): 
    def addFailure(self, test, err): 
     # here you can do what you want to do when a test case fails 
     print('test failed!') 
     super(MyTestResult, self).addFailure(test, err) 

    def addError(self, test, err): 
     # here you can do what you want to do when a test case raises an error 
     super(MyTestResult, self).addError(test, err) 

class MyUT(unittest.TestCase): 
    def test_fail(self): 
     self.assertEqual(1, 2, '123') 
     self.assertTrue("ABc".isupper()) 

if __name__ == '__main__': 
    unittest.main(testRunner=unittest.TextTestRunner(resultclass=MyTestResult)) 

Se si desidera eseguire lavori diversi in base alle diverse classi di test, è possibile ottenerlo in questo modo:

import unittest 

class MyUT(unittest.TestCase): 
    class TestResult(unittest.TestResult): 
     def addFailure(self, test, err): 
      print('do something when test case failed') 
      super(MyUT.TestResult, self).addFailure(test, err) 
     def addError(self, test, err): 
      print('test case error') 
      super(MyUT.TestResult, self).addError(test, err) 

    def test_fail(self): 
     self.assertEqual(1, 2, "1=2") 

class MyUT2(unittest.TestCase): 
    class TestResult(unittest.TestResult): 
     def addFailure(self, test, err): 
      print('do something else when test case failed') 
      super(MyUT2.TestResult, self).addFailure(test, err) 
     def addError(self, test, err): 
      print('test case error') 
      super(MyUT2.TestResult, self).addError(test, err) 

    def test_fail(self): 
     self.assertEqual(1, 2, "1=2") 

if __name__ == '__main__': 
    classes = [MyUT, MyUT2] 
    for c in classes: 
     suite = unittest.TestLoader().loadTestsFromTestCase(c) 
     unittest.TextTestRunner(resultclass=c.TestResult).run(suite) 
0

L'utilizzo di una variabile privata non è molto bello, ma non ho trovato altro modo per accedere all'oggetto che tiene traccia dei risultati del test.

import unittest 

class TmpTest(unittest.TestCase): 

    def tearDown(self): 
     result = self._resultForDoCleanups 
     if not result.wasSuccessful(): 
      print "*** test failed" 

    def testFoo(self): 
     self.assertEqual(2, 2) 

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