我经常发现自己试图稍微滥用 python 允许的一些动态性(我在这里使用 python3,但应该没有太多差异)。
在这种情况下,我想将我的unittest.TestCase
, 中的单个 test_ 方法拆分为在运行时创建的多个方法。
(这是一个关于罗马数字的Kata,但我实际上没有TDD:我后来写了测试)
这是测试:
class TestNumbers(TestCase):
def test_number(self):
for i in range(3000):
self.assertEqual(i, roman_to_int(int_to_roman(i)))
这就是我尝试编写它的方式:
from functools import partial
from types import MethodType
class TestNumbers(TestCase):
pass
def test_number(self, n):
self.assertEqual(n, roman_to_int(int_to_roman(n)))
for i in range(3000):
name = str(i)
test_method = MethodType(partial(test_number, n=i), TestNumbers)
setattr(TestNumbers, "test" + name, test_method)
(或者,我也尝试动态地创建许多 TestCase 子类和setattr(globals(), ...)
它们)
我知道:这并没有太多目的,它也可能更慢,等等。但这只是一个 POC,我正在尝试了解如何让它工作
通过使用 MethodType,测试变成了一个绑定方法,但是在里面,assertEqual 显然变成了一个函数,当试图调用它时它会失败TypeError: assertEqual() takes at least 3 arguments (2 given)
我试图将 test_number 更改为
def test_number(self, n):
self.assertEqual(self, n, roman_to_int(int_to_roman(n)))
但这只会在隐藏的 TestCase 方法中更深地挖掘出同样的问题:TypeError: _getAssertEqualityFunc() takes exactly 3 arguments (2 given)
我在stackoverflow上查看了here并发现了类似的问题(如Python:绑定一个未绑定的方法?),但没有一个涉及绑定一个在其中调用目标类的其他绑定方法的方法
我还尝试研究元类(http://docs.python.org/py3k/reference/datamodel.html#customizing-class-creation),但它似乎与我想要做的不匹配