【问题标题】:What is python's unittest equivalent for BOOST_AUTO_TEST_CASE_TEMPLATEBOOST_AUTO_TEST_CASE_TEMPLATE 的 python 单元测试等效项是什么
【发布时间】:2017-02-13 19:29:02
【问题描述】:

我正在使用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-功能的标准方法是什么?

【问题讨论】:

    标签: python python-2.7 unit-testing


    【解决方案1】:

    Unittest 没有这个功能。您需要使用第三方pytest模块,该模块有extensive support进行参数化测试。

    【讨论】:

    • 这种方法对我来说有两个问题:我不决定应该使用哪些框架,即使我可以,将旧测试移到这个框架上看起来也需要做很多工作。
    • 好吧,不幸的是,这是你唯一的选择;正如我所说,unittest 不支持参数化。有一个tool 可以帮助转换。
    【解决方案2】:

    有两种方法可以到达那里。

    选项 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 参数,因此您需要构建一个套件。有关所有这些,请参阅文档。

    【讨论】:

    • 我选择了选项 1,它工作正常,我只需要稍微调整一下 __init__def __init__(self, *args): unittest.TestCase.__init__(self, *args) self.testclass = Class2。你的版本对你有用吗?
    【解决方案3】:

    @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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多