单元测试:具有多个数据集的相同测试 class
unittest: same test class with mutliple datasets
设置
我正在尝试 运行 在多个数据集上执行相同的 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
这有效
我可以 运行 这 5 个测试 TextTestRunner
from unittest import TextTestRunner
TextTestRunner().run(suite())
效果很好。
失败尝试 1
我想 运行 使用 unittests.main
:
from unittest import main
main(verbosity=3)
一开始 运行 没问题(数字 0, 1, .., 4
通过了测试)但随后第 6 个参数被传递给函数:str
ing '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
六次而不是五次;最后一次用 str
ing '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'
最后我放弃了,转而采用混合类型的方法(这里有一个有 2 个成员的例子:a
和 b
):
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)
设置
我正在尝试 运行 在多个数据集上执行相同的 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
这有效
我可以 运行 这 5 个测试 TextTestRunner
from unittest import TextTestRunner
TextTestRunner().run(suite())
效果很好。
失败尝试 1
我想 运行 使用 unittests.main
:
from unittest import main
main(verbosity=3)
一开始 运行 没问题(数字 0, 1, .., 4
通过了测试)但随后第 6 个参数被传递给函数:str
ing '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
六次而不是五次;最后一次用 str
ing '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'
最后我放弃了,转而采用混合类型的方法(这里有一个有 2 个成员的例子:a
和 b
):
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)