2017-02-13 61 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