2008-10-03 45 views
33

最近發現了這種開發方法,我發現它是一個相當不錯的方法。因此,對於我的第一個項目,我有一個小的DLL值得的代碼(在C#.NET中,它的價值),並且我想爲這個代碼做一組測試,但是我有點失落從哪兒開始。將現有代碼移動到測試驅動開發中

我正在使用NUnit和VS 2008,關於什麼類的入門,寫什麼測試以及關於如何將代碼移動到基於測試的開發的一般技巧的任何提示將會很大讚賞。

回答

53

由邁克爾羽毛見書Working Effectively with Legacy Code

總之,將現有代碼重構爲可測試和測試的代碼有很多工作要做,有時候工作太多,不切實際。它取決於代碼庫的大小,以及各種類和函數相互依賴的程度。

沒有測試的重構會引入行爲(即錯誤)的變化。而純粹主義者會說它並不是真正的重構,因爲缺乏測試來檢查行爲不會改變。

不是一次全線加入測試你的整個應用程序相反,當你在代碼方面的工作添加測試。很可能你必須再次回到這些「熱點」。

從下往上添加測試:測試一些獨立的類和函數以確保正確性。

從上而下添加測試:測試整個子系統的黑盒子,看看他們的行爲與代碼的變化而變化。所以你可以通過它們來了解發生了什麼。這種方法可能會給你帶來最大的好處。

不要太在意先是用「正確」的行爲是什麼,而要添加測試,看看檢測和避免行爲的改變。大的,未經測試的系統通常具有看起來不正確的內部行爲,但系統的其他部分依賴於這些行爲。

想想隔離相關性,如數據庫,文件系統,網絡,使他們能夠在測試過程中被換出的模擬數據提供者。

如果程序沒有內部接口,它定義一個子系統/層和另一個之間的邊界線,則可能必須嘗試引入這些,並且在他們的測試。

另外,像RhinomocksMoq這樣的自動模擬框架可能有助於模擬現有的類。我沒有真正發現他們需要爲可測試性而設計的代碼。

+0

我認爲你的回答對摘要文本要好得多:如果我們想要,我們可以從鏈接中獲得更多詳細信息,但是我們可以在不通讀的情況下理解你的位置。 – 2008-10-03 16:46:59

4

可測試的代碼很容易被發現 - 通過隨附的測試。如果有一些,它必須是可測試的。如果沒有 - 則相反。 ;)

這就是說:測試驅動開發(TDD)不是一個測試策略,而是一個設計策略。你寫的測試首先幫助你設計你的類的接口,以及讓你的類(或者子系統)的範圍正確。

在TDD期間創建並在稍後執行測試的測試可以進行良好的測試,但這只是該設計原理的一個(非常受歡迎的)副作用。

這就是說,期望從你的代碼抵抗被測試的阻力。聽取您的代碼並更改界面以便輕鬆測試。當你開始編寫測試時,你很可能會重新設計它。

+1

我不知道有關測試的阻力,但我已經設法重新揭露了一個早期由VS表單設計師提出的錯誤,這個錯誤通過編寫測試給我帶來了很多麻煩掩蓋這種可能性。好極了! – 2008-10-03 14:33:50

10

Working Effectively with Legacy Code是我的聖經,當涉及到將未經測試的代碼遷移到單元測試的環境中時,它還提供了很多關於如何使代碼易於測試以及如何測試代碼的見解。

我還發現Test Driven Development by ExamplePragmatic Unit Testing: in C# with NUnit是一個體面的介紹,在該環境中的單元測試。

啓動TDD的一個簡單方法是從今天開始先編寫測試,並確保無論何時您需要觸摸現有的(未經單元測試的)代碼,您都會編寫通過測試來驗證系統,然後再對其進行更改,以便您可以重新運行這些測試,以增加您對未破壞任何內容的信心。

1

您的DLL提供某種服務。對於每項服務,您在獲得此服務之前必須做什麼,您應該通過哪些參數來獲得此服務,您如何知道所請求的服務已正確執行?

一旦你擁有了這些問題的答案,你可以寫一個第一次考驗。這樣的測試比單元測試更傾向於稱爲Characterization tests,但如果DLL不是使用TDD開發的,則可能比單元測試更容易編寫。

表徵測試在M.羽毛還討論,這在其他的反應推薦‘修改代碼的工作’。

另外,一定要寫一個失敗的測試之前添加的代碼進行任何新的生產線。

9

我稱之爲「測試驅動逆向工程」。

開始「在底部」 - 每個類可以單獨檢查併爲它寫入一個測試。如有疑問,請猜測。

當你正在做的正向普通TDD,你把測試作爲神聖的,並假定代碼很可能打破。有時測試是錯誤的,但你的起始位置是它的代碼。

當你在做TDRE,代碼是神聖的 - 直到你能證明代碼有一個長期的錯誤。在相反的情況下,您可以編寫測試代碼,調整測試,直到它們工作並聲明代碼有效。

然後,您可以深入瞭解糟糕的代碼。一些不好的凱德會有明智的測試案例 - 這隻需要清理。但是,一些不好的代碼也會有一個毫無意義的測試用例。這可能是一個錯誤,或者你可能會糾正的笨拙設計。

要判斷代碼是否實際錯誤,您還需要從整體測試用例開始。實際運行的實時數據是一個開始。此外,生成任何已知錯誤的實時數據也是開始的好地方。

我寫了很少的代碼生成器來將實時數據轉換爲單元測試用例。這樣,我有一個測試和重構的一致基礎。