Python nose、unittest.TestCase和元类:未发现自动生成的测试方法
这是以下人员的后续问题: 对于此(固定)unittest.TestCase布局:Python nose、unittest.TestCase和元类:未发现自动生成的测试方法,python,unit-testing,metaclass,nose,Python,Unit Testing,Metaclass,Nose,这是以下人员的后续问题: 对于此(固定)unittest.TestCase布局: #!/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
#!/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}_v4,6(self)
for suffix, arg in (('_false', False), ('_true', True)):
testable_name = 'test{0}{1}'.format(testname, suffix)
testable = lambda self, func=meth, arg=arg: func(self, arg)
attrs[testable_name] = testable
return type.__new__(cls, name, bases, attrs)
class TestCase(unittest.TestCase):
__metaclass__ = TestMaker
def test_normal(self):
print 'Hello from ' + self.id()
def _test_this(self, arg):
print '[{0}] this: {1}'.format(self.id(), str(arg))
def _test_that(self, arg):
print '[{0}] that: {1}'.format(self.id(), str(arg))
if __name__ == '__main__':
unittest.main()
这是使用stdlib的框架实现的。预期和实际产出:
C:\Users\santa4nt\Desktop>C:\Python27\python.exe test_meta.py
Hello from __main__.TestCase.test_normal
.[__main__.TestCase.test_that_false] that: False
.[__main__.TestCase.test_that_true] that: True
.[__main__.TestCase.test_this_false] this: False
.[__main__.TestCase.test_this_true] this: True
.
----------------------------------------------------------------------
Ran 5 tests in 0.015s
OK
然而,由于我实际上正在使用,这个技巧似乎不符合它。我得到的结果是:
C:\Users\santa4nt\Desktop>C:\Python27\python.exe C:\Python27\Scripts\nosetests test_meta.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
简而言之,元类生成的test.*
方法不注册到。有人能解释一下吗
谢谢,所以,在对stdlib的
unittest
和nose的loader和selector源代码进行搜索之后,发现nose覆盖了unittest.TestLoader.getTestCaseNames
以使用它自己的选择器(带有插件点)
现在,nose的选择器寻找一个潜在方法的方法。\uuuu name\uuuu
以匹配某些正则表达式、黑白列表和插件的决定
在我的例子中,动态生成的函数的是可测试的。uuu name\uuuu==''
,与nose的选择器标准都不匹配
要解决
# inject methods: test{testname}_v4,6(self)
for suffix, arg in (('_false', False), ('_true', True)):
testable_name = 'test{0}{1}'.format(testname, suffix)
testable = lambda self, arg=arg: meth(self, arg)
testable.__name__ = testable_name # XXX: the fix
attrs[testable_name] = testable
果然:
(sandbox-2.7)bash-3.2$ nosetests -vv
test_normal (test_testgen.TestCase) ... ok
test_that_false (test_testgen.TestCase) ... ok
test_that_true (test_testgen.TestCase) ... ok
test_this_false (test_testgen.TestCase) ... ok
test_this_true (test_testgen.TestCase) ... ok
----------------------------------------------------------------------
Ran 5 tests in 0.005s
OK
看一看。使用
-vv
运行可能会给你提供所需的信息。另外,看看,你知道吗,有人试图做类似的事情。虽然我看过nose的测试生成器,但不幸的是,它不支持从unittest.TestCase
派生的测试类,我需要在该类的子类树中定义夹具。@Santa非常感谢!!这是一个非常有用的例子。