我正在使用unittest
框架,错过了我在Boost.Test
中学会爱的功能。它是BOOST_AUTO_TEST_CASE_TEMPLATE
,在它的帮助下,可以为不同类型运行基本相同的测试,例如
typedef boost::mpl::vector<TypeA, TypeB> types_for_test;
BOOST_AUTO_TEST_CASE_TEMPLATE(test_something, T, types_for_test){
T obj;
BOOST_CHECK_EQUAL(obj.empty(), true);
}
将导致两个不同的单元测试:一个用于类型TypeA
,另一个用于类型TypeB
。
然而,我在unittest
-documentation中找不到任何类型的东西。
因此我的问题是:模拟BOOST_AUTO_TEST_CASE_TEMPLATE
- 功能的标准方法是什么?
答案 0 :(得分:1)
Unittest没有此功能。您需要使用第三方pytest模块,其中extensive support用于参数化测试。
答案 1 :(得分:1)
有两种方法可以实现目标。
选项1
使用unittest
执行所需操作的最简单方法可能是从包含测试方法的超类继承。
class templateMethodsForTesting:
def test_foo(self):
item = self.testclass("some args")
assertEqual(item.foo, 1)
def test_bar(self):
item = self.testclass("other args")
assertEqual(item.bar, 2)
然后继承自unittest.Testcase以及模板:
class testClass1(unittest.Testcase, templateMethodsForTesting):
def __init__(self):
self.testclass = Class1
class testClass2(unittest.Testcase, templateMethodsForTesting):
def __init__(self):
self.testclass = Class2
此时,两个类将具有相同的方法名称,但将是测试发现识别为从Testcase派生的不同类。
自动发现过程应该实例化两者,并在两者上调用所有test*
方法。
选项2
相反,您可以使用对象或类参数将单个测试类参数化到构造函数(__init__
)。然后,您必须自己处理创建测试用例,并将它们组合成一个套件。
类似的东西:
class testSeveralClasses(unittest.Testcase):
def __init__(self, cls):
self.obj = cls()
def test_method1(self):
assertEqual(self.obj.foo, 1)
但是,测试构建器不知道如何提供cls
参数,因此您需要构建一个套件。请参阅所有这些文档。
答案 2 :(得分:0)
@Austin的答案很好(非常感谢!)。但是,在我看来,它只是太多的样板代码。
另一种可能性是为from_templates
类编写一个类装饰器(我们称之为unittest.TestCase
)。装饰器将检查类,找到模板方法并为所有需要的类型创建真实的测试用例。例如:
import unittest
@from_templates([list, set, dict])
class TestBasics(unittest.TestCase):
def template_is_empty(self, type4test):
self.assertEquals(len(type4test()), 0)
与
大致相同import unittest
class TestBasics(unittest.TestCase):
def test_list_is_empty(self):
self.assertEquals(len(list()), 0)
def test_set_is_empty(self):
self.assertEquals(len(set()), 0)
def test_dict_is_empty(self):
self.assertEquals(len(dict()), 0)
我可以在此处找到我对此想法的实现:https://github.com/realead/uttemplate