【问题标题】:unittest: same test class with mutliple datasets单元测试:具有多个数据集的相同测试类
【发布时间】:2019-07-31 09:35:15
【问题描述】:

设置

我正在尝试在多个数据集上运行相同的 unittest.TestCase。我的设置大致如下(尽可能简化):

from unittest import TestCase, TestSuite

class MyTest(TestCase):
    def __init__(self, a, *args, **kwargs):
        super().__init__(methodName="runTest", *args, **kwargs)
        self.a = a

    def setUp(self):
        # something stateful that depends on self.a in the real use case
        self.count = 0

    def tearDown(self):
        del self.count

    def runTest(self):
        self.test_a()

    def test_a(self):
        self.count += 1
        self.assertGreaterEqual(self.a, 0)

test_data = tuple(range(5))
test_cases = tuple(MyTest(a) for a in test_data)

def suite():
    test_suite = TestSuite()
    test_suite.addTests(test_cases)
    return test_suite

这行得通

我可以使用 TextTestRunner 运行这 5 个测试

from unittest import TextTestRunner

TextTestRunner().run(suite())

效果很好。

尝试 1 失败

我想使用unittests.main 运行它:

from unittest import main

main(verbosity=3)

一开始运行良好(数字0, 1, .., 4通过了测试)但随后将第6个参数传递给函数:string 'test_a';这里测试当然失败了。

尝试 2 失败

但终极目标是使用 unittest.TestLoader().discover() 运行它(它将从不同的 python 模块运行):

from unittest import TestLoader
from pathlib import Path


FILE = Path(__file__)
HERE_DIR = Path(FILE).parent
loader = TestLoader()
discovered_suite = loader.discover(start_dir=str(HERE_DIR), pattern=FILE.name)
TextTestRunner().run(discovered_suite)

如果我这样做,loader.discover(...) 行再次初始化 MyTest 六次而不是五次;最后一次是string 'test_a'

问题

如何使用一个TestCase 和多个参数设置此测试,以使我可以使用unittest.TestLoader().discover() 运行它?


我终于找到了可能有帮助的方法:在模块中添加 load_tests 方法:

def load_tests(loader, standard_tests, pattern):
    return suite()

小警告:如上所述,测试仍然是第 6 次初始化......如何避免这种情况?

因为如果MyTest 接受了多个参数:

class MyTest(TestCase):
    def __init__(self, a, b, *args, **kwargs):
        ....

test_cases = tuple(MyTest(a, a) for a in test_data)

当加载器尝试将'test_a' 作为唯一参数传递时,这会使测试崩溃:

TypeError: __init__() missing 1 required positional argument: 'b'

【问题讨论】:

    标签: python python-3.x unit-testing python-unittest


    【解决方案1】:

    最后我放弃了,转而采用 mixin 类型的方法(这里有 2 个成员的示例:ab):

    class MyTest:
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def setUp(self):
            # something stateful in the real use case
            self.count = 0
    
        def tearDown(self):
            del self.count
    
        def runTest(self):
            self.test_a()
    
        def test_a(self):
            self.count += 1
            self.assertGreaterEqual(self.a, 0)
    
    
    class Test0(MyTest, TestCase):
        a = 0
        b = 0
    
    
    class Test1(MyTest, TestCase):
        a = 1
        b = 1
    
    
    if __name__ == "__main__":
    
        main(verbosity=3)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多