2010-03-06 66 views
8

實例類僞代碼:如何測試或描述無盡的可能性?

class SumCalculator 
    method calculate(int1, int2) returns int 

什麼是測試這是一個好辦法嗎?換句話說,我應該如何描述我需要的行爲?

test1: canDetermineSumOfTwoIntegers 

test2: returnsSumOfTwoIntegers 

test3: knowsFivePlusThreeIsEight 

的Test1和Test2的似乎含糊不清,那就需要測試特定的計算,所以它並沒有真正描述的是被測試。然而test3非常有限。

什麼是測試這些類的好方法?

回答

10

我將測試的邊界條件(最大-INT,分鐘-INT,零,正,負)和一些典型的情況:

test1: sumOfPosAndPos 
test2: sumOfPosAndNeg 
test3: sumOfPosAndZero 
test4: sumOfNegAndZero 
test5: sumOfMaxIntAndMinInt 

+1

可能會添加sumOfMaxIntAndMaxInt並檢查報告失敗的函數。這是我能想到的最邊界的情況。 – pmr 2010-03-06 15:51:32

+0

sumOfMaxIntAndOne也應該導致異常,不是嗎?這將是另一個好的邊緣案例。 否則我同意。試想一下幾個可能會有所不同的可能性,然後去解決這個問題。 – 2010-03-07 20:48:15

+1

不要忘記負面測試用例 test6:sumOfStringAndPositive(應該引發異常或返回錯誤) – 2010-03-08 15:57:44

5

有幾種哲學。 Roy Osherove,作者The Art of Unit Testing,似乎是prefer using explicit values,並選擇每個Equivalence Class的最低(或最簡單)表示。

該原理並不適用於您的示例,但在許多其他場景中運行得非常好。

例如,如果一個類需要輸入一個正整數,那麼選擇數字,因爲它是所有正整數的最簡單表示。

個人而言,我更喜歡一個原則,我叫Constrained Non-Determinism。這裏的關鍵是我們讓某種工廠爲我們提供給定類型的匿名變量,因爲它迫使我們直接在測試中建立關係。

我使用AutoFixture做到這一點(但你也可以用別的東西),所以在這種情況下,我會測試這樣的SumCalculator:

var fixture = new Fixture(); 
var int1 = fixture.CreateAnonymous<int>(); 
var int2 = fixture.CreateAnonymous<int>(); 
var expectedResult = int1 + int2; 
var sut = fixture.CreateAnonymous<SumCalculator>(); 

var result = sut.Calculate(int1, int2); 

Assert.AreEqual(expectedResult, result); 

原則上,這種單一的測試提供了一個計算方法的規格。我們永遠不知道int1int2的值是多少,而且在所有那些實際上並不重要的情況下,這是非常合適的。

3

如果你正在測試數學函數,我建議你應該對它的反函數進行測試,例如:對於做x = a + b的函數,你應該測試ax = -b和xb = a ,這僅僅是爲了說明,當然它不適用於每一種情況。

1

此處的另一種替代方法是使用Parameterized Test Case刪除測試中的複製。基本上,一個表包含測試的所有數據,以元組形式([term1,term2,sum]),然後一個測試用例在表上迭代以調用參數化測試用例來測試表中的一行:

I也會增加負數(這裏溢出)測試:什麼是calculate(MAXINT, 1)應該返回?

1

查看David Saff在理論測試方面的工作; here (PDF)就是一個例子。這基本上是一種斷言,某些集合(包括所有可能值的集合)中的某些東西(如函數是其函數的逆函數)是真實的 - 並將該斷言表達爲測試。您可以通過隨機選擇的值運行測試(如果集合太大而無法徹底運行),並將故障自動記錄爲特定的具體迴歸測試,可以做一些有趣的事情。