2012-10-29 44 views
1

單元測試時,如果測試相同方法的邊緣情況需要單獨的測試方法。例如,在測試傳遞給下面的函數一個空字符串:單元測試 - 邊緣案例需要單獨的測試方法嗎?

public function add($numbers) 
{ 
    $numbers = preg_replace('/\s/', '', $numbers); 
    if ($numbers === "") { 
     return 0; 
    } 
} 

我當然想抓住邊緣的情況下,如:

"" 
" " 
"\t \n" 
"asd" 

那麼有多少測試方法是要求證明這種方法有效嗎?

public function testAddEmptyString() 
{ 
    $stringCalculator = new StringCalculator(); 
    $this->assertSame(0, $stringCalculator->add("")); 
} 

public function testAddEmptyStringWithSpaces() 
{ 
    $stringCalculator = new StringCalculator(); 
    $this->assertSame(0, $stringCalculator->add(" ")); 
} 

public function testAddEmptyStringWithCharacters() 
{ 
    $stringCalculator = new StringCalculator(); 
    $this->assertSame(0, $stringCalculator->add("asd")); 
} 

這似乎是測試類會包含什麼不平凡

回答

1

在這個簡單的情況下(實際功能大量的方法,即無副作用,沒有例外,每個測試用例基本上是一條線)我會說單個測試方法會很好。

如果你有更復雜的測試用例需要設置代碼,那麼每個測試用例都應該有自己的測試方法。

0

這是理所當然的一個觀點,所以恕我直言,一種測試方法應該測試一個場景,總是。儘管如此,並且考慮到您應該像生產代碼一樣對待您的測試代碼,您應該爭取一個乾淨的設計 - 在這種情況下,DRY

每種語言都有自己的方法來實現這一點,但通常提取一種方法將有所斬獲。本身,如果進行多次測試,只要它們是孤立的,意圖明確的等等,就沒有害處。

作爲一個例子,xUnit(C#)解決這個問題的方式如下所示:

[Theory] 
[InlineData("")] 
[InlineData(" ")] 
[InlineData("\t \n")] 
[InlineData("asd")] 
public void Add_NonNumber_ZeroReturned(string numbers) 
{ 
    var underTest = new UnderTest(); 
    var result = underTest.Add(numbers); 
    Assert.Equal(0, result); 
} 
0

你應該有很多獨立的測試方法,不要關心它們有多少。

試圖將多重測試用於方法的一個壞處是,當測試失敗時,您不知道破損的真實程度,因爲測試的一部分失敗會阻止測試的其餘部分運行。 (也許聽起來不是那麼糟糕,但是當我試圖修復一個bug時,當我修復時會出現更多的失敗令人沮喪。)如果您組織測試,以便在不同的測試中處理不同的案例,那麼您將立即看到所有失敗。

如果所有邊緣情況都是傳入不同數據的實例,並且它們都以相同方式調用,則可能需要檢查測試框架是否支持參數化測試。

0

您應該有一個與測試分開的所有這些邊緣情況值的數組。

String[] edgeCaseValues = {""," ","\t \n","asd"}; 

然後在一個測試,你可以簡單地循環通過它們傳遞給你的函數

foreach(var edgeCaseValue in edgeCaseValues) 
{ 
    $stringCalculator = new StringCalculator(); 
    $this->assertSame(0, $stringCalculator->add(edgeCaseValue)); 
} 

這樣,那麼你就可以重新使用它們在其他測試中,如果你添加一個新的邊緣案值它們會全部加入到所有測試中