Nose:基于 TestCase 的类的生成器

dom*_*om0 3 python nose python-3.x

我想为 TestCase 派生类的变体创建一个生成器。

我试过的是这样的:

import unittest

def create_class(param):
    class Test(unittest.TestCase):
        def setUp(self):
            pass

        def test_fail(self):
            assert False
    return Test

def test_basic():
    for i in range(5):
        yield create_class(i)
Run Code Online (Sandbox Code Playgroud)

我得到的是这样的:

======================================================================
ERROR: test_1.test_basic
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.3/site-packages/nose/case.py", line 268, in setUp
    try_run(self.test, names)
  File "/usr/lib/python3.3/site-packages/nose/util.py", line 478, in try_run
    return func()
TypeError: setUp() missing 1 required positional argument: 'self'
Run Code Online (Sandbox Code Playgroud)

生成实例而不是类 ( yield create_class(i)()) 给我留下了这个错误:

======================================================================
ERROR: test_1.test_basic
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.3/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/usr/lib/python3.3/unittest/case.py", line 492, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.3/unittest/case.py", line 423, in run
    testMethod = getattr(self, self._testMethodName)
AttributeError: 'Test' object has no attribute 'runTest'
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Bak*_*riu 5

实例化 a 时,TestCase您应该传递测试的方法名称:

yield create_class(i)('test_fail')
Run Code Online (Sandbox Code Playgroud)

否则名称默认为runTest(因此是您得到的最后一个错误)。

另请注意,测试生成器和TestCase. 使用以下代码:

import unittest

def create_class(param):
    class Test(unittest.TestCase):
        def setUp(self):
            pass

        def test_fail(self):
            print('executed')
            assert False
            print('after assert')

    return Test

def test_basic():
    for i in range(5):
        yield create_class(i)('test_fail')
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

$ nosetests -s
executed
.executed
.executed
.executed
.executed
.
----------------------------------------------------------------------
Ran 5 tests in 0.004s

OK
Run Code Online (Sandbox Code Playgroud)

如您所见,即使assert有效,测试也不会失败。这可能是由于TestCase处理了AssertionErrornose不希望处理它的事实,因此它看不到测试失败。

这可以从以下文档中看出TestCase.run

运行测试,将结果收集到作为 传递的测试结果对象中result。如果省略 result 或 None ,则创建一个临时结果对象(通过调用该defaultTestResult()方法)并使用。结果对象不会返回给run()的调用者。

The same effect may be had by simply calling the TestCase instance.
Run Code Online (Sandbox Code Playgroud)

所以,nose没有看到生成器产生的对象是一个TestCase应该以特殊方式处理的对象,它只是期望一个可调用的。在TestCase运行,但结果被放入该丢失的临时对象,这个吃所有的测试失败的试验中这种情况发生。因此,yield TestCasees 根本行不通。