2013-07-29 101 views
0

如果我有簡單的功能,fun1fun2,這需要一些參數測試:蟒單元測試與子功能

class TestOne(unittest.TestCase): 
    def test_func1(self): 
     a = 0 
     b = 1 
     c = 2 
     self.assertEquals(c, fun1(a,b)) 

    def test_fun2(self): 
     d = 0 
     e = 1 
     f = 2 
     self.assertEquals(f, fun2(d,e)) 

和用於第三功能的測試,這需要FUN1的輸出和FUN2作爲輸入

class TestTwo(unittest.TestCase): 

    def test_fun3(self): 
     a = 0 
     b = 1 
     d = 0 
     e = 1 
     g = 3 
     self.assertEquals(g, fun3(fun1(a,b), fun2(d,e))) 

什麼是避免重寫第一個函數參數的最佳方法?

+2

我可以問你爲什麼要在'fun3'的單元測試中使用'fun1'和'fun2'的結果嗎?爲什麼不把fun1和fun2的預期結果放入fun3的測試中?換句話說,如果'fun1(0,1)'返回5並且'fun2(0,1)'返回6,則將'fun3'的測試寫爲'fun3(5,6)'。 –

+0

因爲,從返回值來看,這些功能可能有副作用。 –

+0

@MarkHildreth,因爲我在'fun1'和'fun2'上測試了很多值,在某些情況下,值的差異在最後一位小數,但我有同樣的問題,使用函數作爲單位的輸入是一個好主意測試? – JuanPablo

回答

-1
from functools import partial 

f1 = partial(fun1, a, b) 
f2 = partial(fun2, d, e) 

調用(ref):

f1() 
f2() 

或者你的情況:

f1 = partial(fun1, 0, 1) 
f2 = partial(fun2, 0, 1) 

例子:

In [1]: from functools import partial 

In [2]: def fun1(a, b): 
    ...:  return a + b 
    ...: 

In [3]: f1 = partial(fun1, 0 ,1) 

In [4]: f1() 
Out[4]: 1 
+0

這有何幫助? –

+0

@ Radio-,「避免重寫第一個函數參數的最好方法是什麼?」它可以避免重寫參數 - 解決提問者所面臨的問題。記憶返回值並不總是最好的選擇,因爲功能可能有副作用。 –

0

我相信你也可以創建另一個類。我已經看到了這一點,但我以前沒有做過。如果人們知道這個作品,請留下評論:)而我測試一下自己:

class Tests(unittest.TestCase): 
    def __init__(self): 
     self.a = 0 
     self.b = 1 
     self.c = 2 

class TestOne(Tests): 
    def test_func1(self): 
     self.a 
     self.b 
     self.c 

class TestTwo(Tests): 
    def test_fun3(self): 
     self.a 
     self.b 
     self.c 

UPDATE:通過改變self.a〜Ç類測試(),test_func1 & test_func3在TestOne & TestTwo打印拿出適當的價值。

+1

這是可行的,因爲'TestOne'和'TestTwo'都從'Tests'繼承,因此爲這兩個測試中的每一個調用'Tests .__ init__',導致它們都具有'a','b'和'c'定義。 –

+0

不應該使用'setUpClass'或'setUp'而不是'__init__'嗎? – muppetjones

0
class Base(unittest.TestCase): 
    fun1_val = fun1(a=0, b=1) 
    fun2_val = fun2(d=0, e=1) 

class TestOne(Base): 
    def test_func1(self): 
     c = 2 
     self.assertEquals(c, self.fun1_val) 

    def test_fun2(self): 
     f = 2 
     self.assertEquals(f, self.fun2_val) 

class TestTwo(Base): 
    def test_fun3(self): 
     g = 3 
     self.assertEquals(g, fun3(self.fun1_val, self.fun2_val))   

按製造Basefun1_val和​​類屬性,他們將在被定義Base的時間來計算只有一次。結果可以在以後訪問TestOneTestTwo

+0

'Base'類需要'__init__'? – JuanPablo

+0

'Base'不需要'__init__'。它將繼承'unittest.TestCase .__ init__',這應該可以很好地工作。 – unutbu

+0

在這種情況下,Base類是否真的需要成爲TestCase對象?事實上,你爲什麼要上課?如果這是需要的,只需將值存儲在列表或字典中。更好的是,聲明'setUpClass'並繼承它。 – muppetjones

0

您有幾種選擇:

  1. 我添加在上面這個是每一個其他的答案似乎想用繼承。如果是這樣的話,你只希望每個試驗段(相對於與setUp每個測試)之前設置的值,使用setUpClass

    from unittest import TestCase 
    class BaseTest(TestCase): 
        def setUpClass(cls): 
        cls.a = 0 
        cls.b = 1 
        cls.c = 2 
    
    class TestOne(BaseTest): 
        def test_func1(self): 
        self.assertEquals(self.c, func1(self.a, self.b)) 
    
  2. 使用setUp。如果你經常改變參數,這可能不是最好的解決方案。但是你也可以在基類中定義設置並使用繼承(如其他人所建議的那樣)。

    from unittest import TestCase 
    class TestingSomething(TestCase): 
        def setUp(self): 
        self.parameters = [(0, 1), ] 
    
        def test_func1(self): 
        params = self.parameters[0] 
        res = func1(*params) 
        self.assertEquals(2, res) 
    
  3. 定義幫助函數。

    from unittest import TestCase 
    class TestingSomething(TestCase): 
    
        def param_set_one(self): 
        return (0, 1), 2 
    
        def test_func1(self): 
        params, expected = self.param_set_one() 
        res = self.obj.func1(*params) 
        self.assertEquals(expected, res) 
    
  4. 或許更具體的回答你的問題可能是使用使用一個更具體的輔助功能:

    from unittest import TestCase 
    class TestingSomething(TestCase): 
        def setUp(self): 
        self.obj = TestOne() 
    
        def param_set(self): 
        return (0, 1) 
    
        def get_func1(self): 
        return self.obj.func1(*self.param_set()) 
    
        def get_func2(self): 
        return self.obj.func2(*self.param_set()) 
    
        def test_func1(self): 
        params = self.param_set() 
        res = self.obj.func1(*params) 
        self.assertEquals(2, res) 
        [...] 
        def test_func3(self): 
        retval_func1 = self.get_func1_retval() 
        retval_func2 = self.get_func2_retval() 
        self.assertEqual(3, func3(retval_func1, retval_func2)) 
    

    如果你想你的測試是在單獨的類,只是聲明之外的輔助函數你的測試用例。