假设我有以下 Python UnitTest:
import unittest
def Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Get some resources
...
if error_occurred:
assert(False)
@classmethod
def tearDownClass(cls):
# release resources
...
如果setUpClass调用失败,则不会调用tearDownClass,因此资源永远不会释放。如果下一个测试需要资源,那么在测试运行期间就会出现问题。
当setUpClass调用失败时,有没有办法进行清理?
可以在setUpClass方法中放一个try catch,然后直接在 except 中调用tearDown。
def setUpClass(cls):
try:
# setUpClassInner()
except Exception, e:
cls.tearDownClass()
raise # to still mark the test as failed.
需要外部资源来运行单元测试是不好的做法。如果这些资源不可用,并且您需要测试部分代码是否存在奇怪的错误,您将无法快速运行它。尝试区分集成测试和单元测试。
与保护其他地方的资源的方式相同。
try-except
:
def setUpClass(cls):
# ... acquire resources
try:
# ... some call that may fail
except SomeError, e:
# cleanup here
清理就像在
cls.tearDownClass()
块中调用 except
一样简单。 然后您可以调用assert(False)
或您喜欢的任何方法提前退出测试。
我有一大堆测试辅助函数,它们采用测试实例并使用 addCleanup 来干净地设置/拆除线程、临时文件等,因此我也需要 addCleanup API 来处理类级别的固定装置。我重新实现了一些单元测试 doCleanup 功能来帮助我,并在类设置期间使用模拟来修补 addCleanup()
import unittest
import logging
import mock
LOGGER = logging.getLogger(__name__)
class ClassCleanupTestCase(unittest.TestCase):
_class_cleanups = []
@classmethod
def setUpClassWithCleanup(cls):
def cleanup_fn():
"""Do some cleanup!"""
# Do something that requires cleanup
cls.addCleanup(cleanup_fn)
@classmethod
def addCleanupClass(cls, function, *args, **kwargs):
cls._class_cleanups.append((function, args, kwargs))
@classmethod
def doCleanupsClass(cls):
results = []
while cls._class_cleanups:
function, args, kwargs = cls._class_cleanups.pop()
try:
function(*args, **kwargs)
except Exceptions:
LOGGER.exception('Exception calling class cleanup function')
results.append(sys.exc_info())
if results:
LOGGER.error('Exception(s) raised during class cleanup, re-raising '
'first exception.')
raise results[0]
@classmethod
def setUpClass(cls):
try:
with mock.patch.object(cls, 'addCleanup') as cls_addCleanup:
cls_addCleanup.side_effect = cls.addCleanupClass
cls.setUpClassWithCleanup()
except Exception:
cls.doCleanupsClass()
raise
@classmethod
def tearDownClass(cls):
cls.doCleanupsClass()
与此同时,
addClassCleanup
类方法已添加到unittest.TestCase
中,正是为了这个目的:https://docs.python.org/3/library/unittest.html#unittest.TestCase.addClassCleanup