2017-02-13 58 views
0

我正在使用unittest框架,并且错过了我在Boost.Test中学会爱的功能。这是BOOST_AUTO_TEST_CASE_TEMPLATE,并与它的帮助下可以基本上运行不同类型相同的测试,例如什么是BOOST_AUTO_TEST_CASE_TEMPLATE的python单元测试等价物

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 -Functionality的标准呢?

回答

0

@Austin的答案工作正常(感谢很多关于这一点!)。但是,在我看来,这只是太多的样板代码。

另一种可能性是为类unittest.TestCase写一个类装饰器(我们称之为from_templates)。装饰器将检查类,找到模板方法并为所有需要的类型创建真正的测试用例。例如:

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

1

单元测试不具备此功能。您需要使用第三方pytest模块,其中extensive support用于参数化测试。

+0

有两个问题,这种做法对我说:我不不能决定应该使用哪种框架,即使可以,也应该将旧测试移到这个框架中,这看起来很多工作。 – ead

+0

不幸的是,这是你唯一的选择;正如我所说的,unittest不支持参数化。有一个[工具](https://pypi.python.org/pypi/unittest2pytest/)来帮助转换。 –

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参数,所以你需要建立一套。请参阅所有文档。

+0

我选择了选项1,它工作正常,我只需要稍微调整一下__init__:def __init __(self,* args): unittest.TestCase .__ init __(self,* args) self.testclass = Class2'。你的版本是否适合你? – ead