【问题标题】:nose test class with generator for multiple tests but only one instance of the class带有生成器的鼻子测试类,用于多个测试,但只有一个类实例
【发布时间】:2015-05-22 13:45:22
【问题描述】:

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

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

关于如何让鼻子做到这一点的任何想法?

【问题讨论】:

    标签: generator nose nosetests


    【解决方案1】:

    两种方法可以得到你想要的: 为您的 TestUmbrella 使用 unittest.TestCase 类和 setUpClass:

    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')
    

    请注意,您将不再能够即时生成东西,并且必须重命名方法以符合鼻子测试模式。这会给你:

    $ 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
    

    或者,您可以将 setup 方法注入到类中,但不能作为类初始化的一部分:

    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
    

    【讨论】:

    • 通过这两种方法,nose 仍然会创建三个 TestUmbrella 实例。我试图找到一种方法让鼻子运行三个测试用例,但从一个 TestUmbrella 实例开始。
    • 已更新以显示如何获取 TestUmbrella 类的单个实例。
    • 现在我为什么没有想到呢? :) 谢谢,这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2012-06-26
    • 1970-01-01
    相关资源
    最近更新 更多