2008-10-04 129 views
6

作爲基於測試的開發新手,這個問題一直困擾着我。多少是太多了?應該測試什麼,應該如何測試以及爲什麼要測試它?給出的例子是用NUnit在C#中,但我認爲這個問題本身是語言不可知的。測試用例,「什麼時候」,「什麼」和「爲什麼」?

下面是我自己的兩個電流的例子,一個泛型列表對象測試(被用繩子測試,初始化函數添加三個項目{"Foo", "Bar", "Baz"}):

[Test] 
public void CountChanging() 
{ 
    Assert.That(_list.Count, Is.EqualTo(3)); 
    _list.Add("Qux"); 
    Assert.That(_list.Count, Is.EqualTo(4)); 
    _list[7] = "Quuuux"; 
    Assert.That(_list.Count, Is.EqualTo(8)); 
    _list.Remove("Quuuux"); 
    Assert.That(_list.Count, Is.EqualTo(7)); 
} 

[Test] 
public void ContainsItem() 
{ 
    Assert.That(_list.Contains("Qux"), Is.EqualTo(false)); 
    _list.Add("Qux"); 
    Assert.That(_list.Contains("Qux"), Is.EqualTo(true)); 
    _list.Remove("Qux"); 
    Assert.That(_list.Contains("Qux"), Is.EqualTo(false)); 
} 

的代碼是相當自我註釋的,所以我不會介入發生的事情,但是這種事情是否過分了? Add()Remove()當然是單獨測試的,那麼我應該對這些測試進行什麼級別的測試?我是否應該進行這些測試?

回答

7

我會說你實際測試的是等價類。在我看來,添加到具有3個項目或7個項目的列表之間沒有區別。但是,0項目,1項目和> 1項目之間存在差異。我最初可能會針對這些案例分別進行3次添加/刪除方法的測試。

一旦錯誤從QA /用戶開始傳入,我會將每個此類錯誤報告添加爲測試用例;通過獲得一個紅色條看到錯誤再現;通過獲得綠色條來修復錯誤。每個這樣的'缺陷檢測'測試都會留下來 - 這是我的安全網(閱讀:迴歸測試),即使我再次犯這個錯誤,我也會立即得到反饋。

1

_list你寫的一個類的實例嗎?如果是這樣,我會說測試它是合理的。雖然在這種情況下,你爲什麼要構建一個自定義List類?

如果它不是你寫的代碼,除非你懷疑它是以某種方式出錯,否則不要測試它。


我嘗試測試獨立和模塊化的代碼。如果我需要維護代碼中的某種上帝功能,我會盡可能多地去掉子功能並獨立地測試它們。然後,上帝的功能可以寫成「顯然是正確的」 - 沒有分支,沒有邏輯,只是將結果從一個經過良好測試的子功能傳遞給另一個。

+0

這是我自己的代碼,並在寫作測試實際上暴露了錯誤,即使我沒有懷疑它是越野車。至於我爲什麼要重新發明輪子,我需要一個List 類型類,它支持添加/刪除項目時發生的事件等。 – 2008-10-04 06:59:42

+0

因爲它是您的代碼,那麼是的,請爲它編寫測試。即使寫他們是無聊或感到浪費,每一個非平凡課程的測試都可以避免一小段時間的挫折感。我不用C#寫的唯一測試就是{get; set;}屬性。 – 2008-10-04 07:02:50

+0

爲什麼不只是爲默認通用列表編寫一個裝飾器,在add/remove上觸發這些事件,將實際工作傳遞給超類? – jdmichal 2009-02-17 20:10:07

6

將您的測試視爲規範。如果你的系統在沒有測試失敗的情況下可能中斷(或者有重大錯誤),那麼你的測試覆蓋率不足。如果單點故障導致許多測試中斷,那麼您可能有太多(或者耦合太緊)。

這實在很難用客觀的方式來定義。我想我會在測試方面犯錯。然後,當測試開始困擾你時,那些測試就是重構/重用的特定測試(因爲它們太脆弱了,或者測試了錯誤的東西,而且它們的失敗沒有用)。

2

一些提示:

  1. 每個測試用例應該只測試一兩件事。這意味着測試用例的結構應該是「設置」,「執行」,「斷言」。在你的例子中,你混合了這些階段。試着分開你的測試方法。這使得更容易看到你正在測試的東西。

  2. 試着給你的測試方法一個名稱,描述它正在測試的內容。即包含在ContainsItem()中的三個測試用例變爲:containsReportsFalseIfTheItemHasNotBeenAdded(),containsReportsTrueIfTheItemHasBeenAdded(),containsReportsFalseIfTheItemHasBeenAddedThenRemoved()。我發現強迫自己想出一個描述性的名字,這有助於我在編寫實際測試之前將我必須測試的內容概念化。

  3. 如果您執行TDD,則應該編寫測試優先級,並在測試失敗時僅將代碼添加到實施中。即使你沒有真正做到這一點,它會讓你知道有多少測試就足夠了。或者使用覆蓋工具。對於像容器這樣的簡單課程,您應該瞄準100%的覆蓋率。

相關問題