当使用python 3中的unittest
库时,我只想在测试失败时做一些操作(但这应该在类级别,所以我不必为每个测试编写它)。例如,当使用 behave 时,有类似的东西:
def after_step(context, step):
if step.status == "failed":
...
unittest
库是否有类似内容,如果没有,那么做类似的最简单的方法是什么?
答案 0 :(得分:4)
我最近尝试做类似的事情,我找到了出路:
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))
如果你想根据不同的测试用例类做不同的工作,你可以这样做:
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)
答案 1 :(得分:1)
您可以尝试使用装饰器:
class ExceptionHandler(object):
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
try:
self.f(*args, **kwargs)
except:
print('do smth')
在单元测试中:
@ExceptionHandler
def test_fail(self):
self.assert_false(True)
答案 2 :(得分:0)
您可以对这些很酷的东西。通过调用原始设置的自定义覆盖默认异常处理程序,并设置自定义属性:
import sys
import unittest
has_failures = []
class IntegrationTests(unittest.TestCase):
old_failureException = unittest.TestCase.failureException
@property
def failureException(self):
has_failures.append('fail')
return self.old_failureException
def setUp(self):
sys.stderr.write('Setup for %s\n' % self._testMethodName)
if has_failures:
self.skipTest("An test has failed, skipping everything else!")
def test_thing1(self):
self.assertEqual(1, 2)
def test_thing2(self):
pass
def load_tests(loader, standard_tests, pattern):
suite = unittest.TestSuite()
suite.addTest( IntegrationTests( 'test_thing1' ) )
suite.addTest( IntegrationTests( 'test_thing2' ) )
return suite
# Comment this to run individual Unit Tests
load_tests = None
if __name__ == "__main__":
unittest.main(verbosity=3)
结果:
test_thing1 (__main__.IntegrationTests) ... Setup for test_thing1
FAIL
test_thing2 (__main__.IntegrationTests) ... Setup for test_thing2
skipped 'An test has failed, skipping everything else!'
======================================================================
FAIL: test_thing1 (__main__.IntegrationTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\User\Downloads\text.py", line 27, in test_thing1
self.assertEqual(1, 2)
AssertionError: 1 != 2
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1, skipped=1)
参考文献:
答案 3 :(得分:-1)
使用私有变量不是很好,但我还没有找到其他方法来访问跟踪测试结果的对象。
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()