2010-08-30 56 views
1

假設我們正在設計一個Stack類測試第一(TDD):關於幾個問題的單元測試

public class Stack<T> { 
    private T[] elements = new T[16]; 
    private int size = 0; 
    ... 
} 

這個堆棧利用了大小16個內部數組來存儲它的元素。它會正常工作,直到你需要添加第17個元素。因爲我可能需要第17個元素,所以我決定將該功能添加到我的堆棧中,所以我開始考慮可以給測試添加哪些名稱,以便添加該功能。這將是我的第一個問題的主題。

我首先選擇的形式的東西:

Should_Be_Able_To_Correctly_Increase_Its_Inner_Array_Size() 

然後

Should_Handle_More_Items_Than_The_Default_Internal_Array_Size() 

但想了一會兒後,我得出的結論,也許像下面這樣會比較apropriate :

Should_Double_Its_Size_Every_Time_Its_Full() 

我的推理必須在第一種情況下這樣做,我說只有它做什麼,但不是什麼時候。 第二,我說什麼時候添加更多的項目,但我也說明我是如何在內部實現它的,這可能是不正確的。在我看來(我不確定我是否正確),我的測試應該是我的SUT與外部可能的相互作用,而不是內部如何實現。我對嗎?

它在我看來,第三個選項是最好的,因爲它清楚地說明了它的作用(增長的規模 - 事實上,它的大小的兩倍),當它(當它已滿),並沒有聯繫我到任何特定的實現(我可能以後可能想要將其更改爲內部ArrayList!)。

這使我對我的第二個問題:假設我做了所有的單元測試我的Stack類在內部使用數組和它工作正常,符合預期,應我的測試中保持不變,如果我以後要重構並將數組更改爲ArrayList或任何其他類型的數據結構?還是應該以任何方式反映這些測試?我猜不,但我不確定。

+0

對我來說似乎你的測試不應該對內部工作做出假設。如果稍後您選擇更改某些內部實現細節,則不需要重寫所有測試。 – Mark 2010-08-30 19:12:01

回答

3

在我看來(我不知道我 正確的),我的測試應該我SUT的可能 相互作用與 外部,而不是它是如何 內部實現。我對嗎?

你是對的。如果你改變你的類的內部實現,單元測試應該保持不變。如果您在外部暴露任何新內容,則應該創建新的單元測試來說明這些更改。

請記住,當你設計你的課程時,你不想公開任何表明它是如何實現的。班上的公共成員指出如何與它互動,現在它在幕後如何運作。

2

我不知道如何通過單元測試來測試內部列表或數組大小。您無法通過堆棧接口訪問它。單元測試用於測試外部合同。如果你想測試實現細節,那麼嘗試其他的東西。

第二個問題的答案是肯定的,如果是單元測試,測試仍然應該通過。

+0

當做這個類的TDD風格時,我會做什麼樣的測試呢? – 2010-08-30 20:06:02

+0

測試外部接口並確保它按預期工作。 – 2010-08-31 05:26:59

1

我不確定應該通過單元測試測試內部列表或數組大小,因爲您無法通過堆棧接口訪問它。實現堆棧的方法有很多,有些很好,有些很糟糕,但正如Bernard所說,這些是內部實現。單元測試旨在測試外向功能。

2

問問你自己,你願意爲這門課承擔什麼。

您或班級的消費者真的關心容量是否增加一倍或增加一千?如果是這樣,你應該修改界面,讓他們可以指定用於增加容量的策略:

public Stack<T>(CapacityGrowthStyle capacityGrowthStyle) { ... } 

如果沒有,只是寫測試記錄的能力,並留在這一點(其中下面X是基礎數據結構的限制):

[Test] 
public void Can_Handle_X_Items() { ... } 

[Test] 
[ExpectedException(typeof(InvalidOperationException))] 
public void Cannot_Handle_More_Than_X_Items() { ... } 

我會回答你的第二個問題類似:你的測試應該只反映底層數據結構,如果你的類的用戶會在意它。

+0

我明白了你的觀點。現在,如果我遵循TDD指南,我應該如何添加這個「功能」?現在我明白了,那是我的主要問題! – 2010-08-30 20:07:23

+1

@devoured - 這是一個有趣的(和困難的)問題。如果容量增長算法對我的用戶來說真的很重要(推測是出於性能原因),我會試圖添加一個'容量'屬性來促進測試,即使用戶可能通常不需要該屬性。但是我會對API的混亂感到一些遺憾。 ( – 2010-08-30 20:30:29

+0

)但是讓我們說,我的用戶不會想知道它。使用測試優先方法,我應該只添加一些特定的功能,如果我先測試它的測試,但在這種情況下,我會如何解決這個問題? – 2010-08-30 20:41:44