鼻子测试 class 带有用于多项测试的生成器,但只有 class 的一个实例

nose test class with generator for multiple tests but only one instance of the class

我正在尝试找到一种方法来使用 nose 运行 class 中的多个测试用例,但我需要这样做,其中 nose 只创建一个 class .此 class 将测试网络,网络设置需要几分钟,因此需要 运行 通过 class 的一个实例进行所有测试。这是我正在尝试做的一个基本示例:

class TestUmbrella(object):

    def __init__(self):
        log.info('__init__ called')

    def run_A(self):
        log.info('Test A is running')

    def run_B(self):
        log.info('Test B is running')

    def run_C(self):
        log.info('Test C is running')

    def run_test(self):
        for x in (self.run_A, self.run_B, self.run_C):
            yield x

这会产生:

 2015-03-19 12:22:31,330:   INFO:       tests.l3.FooTest2: __init__ called
 2015-03-19 12:22:31,331:   INFO:       tests.l3.FooTest2: __init__ called
 2015-03-19 12:22:31,331:   INFO:       tests.l3.FooTest2: Test A is running
.2015-03-19 12:22:31,331:   INFO:       tests.l3.FooTest2: __init__ called
 2015-03-19 12:22:31,332:   INFO:       tests.l3.FooTest2: Test B is running
.2015-03-19 12:22:31,332:   INFO:       tests.l3.FooTest2: __init__ called
 2015-03-19 12:22:31,332:   INFO:       tests.l3.FooTest2: Test C is running
.
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK

我想看的是:

 2015-03-19 12:22:31,330:   INFO:       tests.l3.FooTest2: __init__ called
 2015-03-19 12:22:31,331:   INFO:       tests.l3.FooTest2: Test A is running
 2015-03-19 12:22:31,332:   INFO:       tests.l3.FooTest2: Test B is running
 2015-03-19 12:22:31,332:   INFO:       tests.l3.FooTest2: Test C is running

关于如何让鼻子做到这一点有什么想法吗?

两种方式获得你想要的东西: 将 unittest.TestCase class 与 setUpClass 一起用于您的 TestUmbrella:

from unittest import TestCase
import logging as log

class TestUmbrella(TestCase):
    @classmethod
    def setUpClass(cls):
        log.info('__init__ called')

    def run_A_test(self):
        log.info('Test A is running')

    def run_B_test(self):
        log.info('Test B is running')

    def run_C_test(self):
        log.info('Test C is running')

请注意,您将无法再即时产生结果,并且必须重命名方法以符合 nose 测试模式。那会给你:

$ nosetests cls_test.py -v
INFO:root:__init__ called
run_A_test (cls_test.TestUmbrella) ... INFO:root:Test A is running
ok
run_B_test (cls_test.TestUmbrella) ... INFO:root:Test B is running
ok
run_C_test (cls_test.TestUmbrella) ... INFO:root:Test C is running
ok

----------------------------------------------------------------------
Ran 3 tests in 0.007s

OK

或者,您可以将设置方法注入 class,但不作为 class 初始化的一部分:

import logging as log

class TestUmbrella(object):
    def my_setup(self):
        log.info('__init__ called')

    def run_A(self):
        log.info('Test A is running')

    def run_B(self):
        log.info('Test B is running')

    def run_C(self):
        log.info('Test C is running')

    def run_test(self):
        self.my_setup()
        for x in (self.run_A, self.run_B, self.run_C):
            yield x

最后,如果您真的无法从构造函数中卸载繁重的逻辑,您可以 运行 从独立函数中进行测试,如下所示:

def run_test():
    tu = TestUmbrella()
    for x in (tu.run_A, tu.run_B, tu.run_C):
        yield x