Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python nose、unittest.TestCase和元类:未发现自动生成的测试方法_Python_Unit Testing_Metaclass_Nose - Fatal编程技术网

Python nose、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

这是以下人员的后续问题:

对于此(固定)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
            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非常感谢!!这是一个非常有用的例子。