gpt4 book ai didi

python - 单元测试和元类 : automatic test_* method generation

转载 作者:太空狗 更新时间:2023-10-30 02:35:01 24 4
gpt4 key购买 nike

当我为框架创建测试时,我开始注意到以下模式:

class SomeTestCase(unittest.TestCase):

def test_feat_true(self):
_test_feat(self, True)

def test_feat_false(self):
_test_feat(self, False)

def _test_feat(self, arg):
pass # test logic goes here

所以我想以编程方式为这些类型的带有元类的测试类创建 test_feat_* 方法。换句话说,对于每个带有签名 _test_{featname}(self, arg) 的私有(private)方法,我想要两个带有签名 test_{featname}_true(self) 的顶级可发现方法test_{featname}_false(self) 被创建。

我想到了类似的东西:

#!/usr/bin/env python

import unittest


class TestMaker(type):

def __new__(cls, name, bases, attrs):
callables = dict([
(meth_name, meth) for (meth_name, meth) in attrs.items() if
meth_name.startswith('_test')
])

for meth_name, meth in callables.items():
assert callable(meth)
_, _, testname = meth_name.partition('_test')

# inject methods: test{testname}_{[false,true]}(self)
for suffix, arg in (('false', False), ('true', True)):
testable_name = 'test{0}{1}'.format(testname, suffix)
attrs[testable_name] = lambda self: meth(self, arg)

return type.__new__(cls, name, bases, attrs)


class TestCase(unittest.TestCase):

__metaclass__ = TestMaker

def _test_this(self, arg):
print 'this: ' + str(arg)

def _test_that(self, arg):
print 'that: ' + str(arg)


if __name__ == '__main__':
unittest.main()

我希望得到如下输出:

this: False
this: True
that: False
that: True

但是我得到的是:

$ ./test_meta.py
that: True
.that: True
.that: True
.that: True
.
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

看起来我缺少一些关闭规则。我该如何解决这个问题?有没有更好的方法?

谢谢,

编辑:已修复。请参阅:the snippet .

最佳答案

确实是闭包问题:

改变

attrs[testable_name] = lambda self: meth(self, arg)

attrs[testable_name] = lambda self,meth=meth,arg=arg: meth(self, arg)

通过使用默认值,lambda 内部的 arg 绑定(bind)到在循环的每次迭代期间设置的默认值 arg。如果没有默认值,arg 将在循环的所有迭代完成后采用 arg 的最后一个值。 (meth 也是如此)。

关于python - 单元测试和元类 : automatic test_* method generation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5175942/

24 4 0