棘手! :-)
这里的问题是你不知道下一个要调用的函数是什么——不是
不直接干扰单元测试代码。
但是,如果可以将每个测试用例更改为另一种方法,
这将调用为该测试用例定制的“设置”,然后执行原始的
测试用例,就解决了。
换句话说:需要自动更改您声明的类中的每个测试用例
进入另一个功能:执行个性化设置,然后他们执行
原始测试。这应该在类创建时完成。
这可能看起来很复杂,但它相当适合“元类” - 因为我们只是在做它们的本意:自定义类的创建。
因此,通过将 TestCase 的元类更改为检查类中每个项目的元类 -
如果它是一个测试(即,如果它的名称以“test”开头),则创建一个新的包装函数
完成上述功能,你就可以开始了。
(还需要进一步的步骤:由于方法名称和(用于)原始测试方法的(对象)在创建后必须保持不变,因此必须创建一个中间函数来为每个测试用例保留闭包。否则,下面代码中的变量method_name和original_method都将设置为for循环结束时类中最后一个函数的名称和内容)
你去吧:
# -*- coding: utf-8 -*-
import unittest
import logging
#template method:
def log_setup(self, name):
#self.hdl = logging.FileHandler('testcase_%s.log' % name, mode='w')
#log.addHandler(self.hdl)
self.name = name
class MetaTestCase(type):
def __new__(cls, cls_name, bases, dict):
for name, item in dict.items():
if name.startswith("test"):
def scope_freezer(method_name, original_method):
def wrapper(self, *args, **kw):
log_setup(self, method_name)
return original_method(self, *args, **kw)
return wrapper
dict[name] = scope_freezer(name, item)
return type.__new__(cls, cls_name, bases, dict)
class TestExample(unittest.TestCase):
__metaclass__ = MetaTestCase
def test_a(self):
print self.name
def test_b(self):
print self.name
def tearDown(self):
pass
#log.removeHandler(self.hdl)
unittest.main()
(为了简化我这边的测试,我注释掉了实际的日志记录行 - “打印”工作正常 - log_setup 函数中的任何代码都将在 self 和 name 正确设置的情况下运行。)
当然,您可以将这个元类分解到另一个模块中,然后将其导入以用于您的测试。