2008-08-02 36 views
18

我想用一組條紋和正常值的元組來測試一個函數。例如,當測試一個返回true的函數時,無論何時給定三個長度形成一個有效的三角形,我都會有特定的情況,負數/小數/大數,接近於溢出的值等。更重要的是,主要目的是生成這些值的組合,而不是重複,以獲得一組測試數據。如何使用組合的集合作爲測試數據

(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf), 
... 

作爲一個說明:其實我知道這個問題的答案,但它可能是別人有幫助,併爲這裏的人們是一個挑戰! - 稍後會發布我的答案。

+0

[Abacus github](https://github.com/foo123/Abacus)一個用於Node.JS,Python,PHP,Actionscript的組合函數庫 – 2015-03-05 23:04:49

回答

14

絕對的,特別是處理大量這些排列/組合我肯定可以看到,第一遍將是一個問題。

python中有趣的實現,雖然我在C和Ocaml基於「算法515」(見下文)寫了一個很好的實現。他在Fortran中撰寫了他的論文,因爲那時所有的「算法XX」論文都很常見,那就是程序集或c。我不得不重新編寫它,並進行一些小改進,以使用數組而不是數字範圍。這是一個隨機訪問,我仍然在努力獲得Knuth 4卷第2卷中提到的一些很好的實現。我將解釋這是如何對讀者起作用的。雖然如果有人好奇,我不會反對寫點東西。

/** [combination c n p x] 
* get the [x]th lexicographically ordered set of [p] elements in [n] 
* output is in [c], and should be sizeof(int)*[p] */ 
void combination(int* c,int n,int p, int x){ 
    int i,r,k = 0; 
    for(i=0;i<p-1;i++){ 
     c[i] = (i != 0) ? c[i-1] : 0; 
     do { 
      c[i]++; 
      r = choose(n-c[i],p-(i+1)); 
      k = k + r; 
     } while(k < x); 
     k = k - r; 
    } 
    c[p-1] = c[p-2] + x - k; 
} 

〜 「算法515:從辭書索引向量的一代」; Buckles,B.P。和Lybanon,M.ACM Transactions on Mathematical Software,Vol。 3,第2期,1977年6月。

+0

`choose()`做什麼?這基本上會返回`n-c [i]`選擇'p-(i + 1)1`嗎? – mkb 2012-02-28 04:01:34

4

有趣的問題!

我會通過選擇組合來做到這一點,就像在python中的以下內容。最難的部分可能是第一次通過驗證,即if f(1,2,3) returns true,這是一個正確的結果?一旦你證實了這一點,那麼這是迴歸測試的良好基礎。

也許這是一個好主意,可以讓你知道的一組測試用例都是真實的(例如3,4,5這個三角形的情況),並且你知道的一組測試用例都是假的例如0,1,inf)。然後,您可以更輕鬆地驗證測試是否正確。

 
# xpermutations from http://code.activestate.com/recipes/190465 
from xpermutations import * 

lengths=[-1,0,1,5,10,0,1000,'inf'] 
for c in xselections(lengths,3):  # or xuniqueselections 
    print c 
 
(-1,-1,-1); 
(-1,-1,0); 
(-1,-1,1); 
(-1,-1,5); 
(-1,-1,10); 
(-1,-1,0); 
(-1,-1,1000); 
(-1,-1,inf); 
(-1,0,-1); 
(-1,0,0); 
... 
2

我認爲你可以用Row Test Attribute(在MbUnit和更高版本的NUnit中可用)做到這一點,你可以指定幾組來填充一個單元測試。

0

儘管可以創建大量測試數據並查看會發生什麼,但嘗試最小化正在使用的數據會更有效。

從典型的QA角度來看,您需要識別不同的輸入分類。爲每個分類生成一組輸入值並確定適當的輸出。

下面是輸入的類別的樣本值

  • 有效三角形具有小的數字,如(1十億,2,十億,2十億)
  • 具有大量如(0.000001,0.00002有效三角形,0.00003)
  • 有效鈍角三角形是「almost'flat如(10,10,19.9999)
  • 有效急性三角形是 '幾乎' 平的,如(10,10,0000001)
  • 無效三角形無線個的至少一個負值
  • 無效三角形,其中兩側的總和等於所述第三
  • 無效三角形,其中兩個邊的總和大於那些非數字的第三
  • 輸入值更大

...

一旦您對此功能的輸入分類列表感到滿意,您就可以創建實際的測試數據。可能的話,測試每個項目的所有排列會很有幫助。 (例如(2,3,4),(2,4,3),(3,2,4),(3,4,2),(4,2,3),(4,3,2))通常情況下,您會發現您錯過了一些分類(例如inf作爲輸入參數的概念)。

某段時間的隨機數據也可能有幫助,可以在代碼中發現奇怪的錯誤,但通常效率不高。

更有可能的是,這個函數在某些應用了附加規則的特定環境下使用(例如,只有整數值或值必須以0.01爲增量等)。這些添加到輸入參數分類列表中。

4

隨着品牌新的Python 2.6,你和itertools模塊返回iterables的笛卡爾乘積的標準溶液:

import itertools 

print list(itertools.product([1,2,3], [4,5,6])) 
    [(1, 4), (1, 5), (1, 6), 
    (2, 4), (2, 5), (2, 6), 
    (3, 4), (3, 5), (3, 6)] 

您可以提供一個「重複」的說法與可迭代進行產品和本身:

print list(itertools.product([1,2], repeat=3)) 
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), 
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)] 

你也可以調整與組合的東西還有:

print list(itertools.combinations('123', 2)) 
[('1', '2'), ('1', '3'), ('2', '3')] 

如果順序的問題,也有排列:

print list(itertools.permutations([1,2,3,4], 2)) 
[(1, 2), (1, 3), (1, 4), 
    (2, 1), (2, 3), (2, 4), 
    (3, 1), (3, 2), (3, 4), 
    (4, 1), (4, 2), (4, 3)] 

當然所有的酷的東西不完全做同樣的事情,但你可以在某種程度上使用它們或其他解決你的問題。請記住,您可以使用list(),tuple()和set()將元組或列表轉換爲集合,反之亦然。