2010-07-16 25 views
9

我在家玩玩具項目,以更好地瞭解測試驅動設計。起初事情似乎進展順利,我陷入了失敗的測試,代碼,通過測試的搖擺。測試驅動設計 - 我哪裏錯了?

然後,我來添加一個測試,並意識到這將是困難的,我目前的結構,此外,我應該分裂一個具有太多責任的特定班級。爲下一次測試增加更多的責任顯然是錯誤的。我決定擱置這個測試,並重構我的東西。這是事情開始出錯的地方。

很難重新構建而不會一次打破很多測試,然後唯一的選擇似乎是做出很多改變,並希望我最終回到測試再次通過的地方。測試本身是有效的,我只是在重構時幾乎打破了所有這些測試。重構(我仍然不滿意)在我回到所有測試通過之前花了我五六個小時。這些測試確實幫助我一路走來。

感覺就像我走下了TDD賽道。你覺得我做錯了什麼?

由於這主要是一個學習練習,我正考慮回滾所有重構,並試圖以更好的方式再次前進。

+3

我喜歡學習的承諾。我認爲回滾和應用@ phillipe的答案是一個好主意。 – btlog 2010-07-16 12:27:44

回答

8

也許你在分班時速度太快了。是的Extract Class Refactoring的步驟如下:

  • 創建新類
  • 有一個類的實例作爲私有數據成員
  • move field到新類,一個接一個
  • 編譯和測試的每個字段
  • move method到新的類,一個接一個,測試每個

這樣你就不會在重構你的課程的時候打破大量的測試,並且你可以依靠測試來確保課堂分裂到目前爲止沒有任何東西被打破。

另外,請確保您的測試行爲是,而不是執行

+1

+1。您也可以以測試驅動的方式進行此過程。暫時擱置Move Field:當您準備將Method M移動到新類時,首先將您的單元測試重新定向到M,然後將測試本身移動到不同的類。當M移動時,你的測試應該編譯並通過。 – 2010-07-16 13:17:52

+0

感謝您的回答,我可能會修改代碼並嘗試此操作。如果沒有過多的代碼,很難解釋,但我試圖分離的責任是「用戶想要發生的事情」和「允許發生的事情」。這些概念混合在我已經認識的課堂上。 – 2010-07-16 13:26:07

+0

不要忘記使用依賴注入提取類到舊類 – Gutzofter 2010-07-16 15:49:33

0

也許你正在測試一個太低的水平。很難說沒有看到你的代碼,但通常我會從頭到尾測試一個特性,並確保我預期發生的所有行爲都發生了。單獨測試每一種方法都會爲您提供您創建的測試網絡。

您可以使用像NCover和DotCover這樣的工具來檢查您是否錯過了任何代碼路徑。

+0

我的測試一般是:構建域模型的某些部分,從(模擬)用戶界面給它一個或兩個事件,並通過查詢域模型來聲明結果。我的測試使用與UI層相同的界面,因爲我自上而下構建它。 (其他一些測試只是對某個特定類進行單元測試才能獲得)。 – 2010-07-16 12:24:41

+1

單元測試正在測試每個單獨的方法。 TDD在編碼實施之前正在創建單元測試。 – btlog 2010-07-16 12:26:24

+0

我稱之爲「單元測試」的測試仍然是首先編寫的。他們只專注於一個班級。其他人有更大的範圍(從模擬的GUI事件開始,直到模擬的GUI結果)。 – 2010-07-16 12:41:01

0

唯一「錯誤的」是之後添加測試。在「真實」TTD中,您首先在實際執行之前聲明所有測試。我說「真」,因爲那通常只是理論。但在實踐中,你仍然有測試給出的安全性。

+0

我認爲他的意思是說,他在做一些工作之後添加的測試是針對新功能的,而不是針對現有的代碼。 – 2010-07-16 12:26:47

+0

我打算爲下一個功能添加一個測試,當我意識到如果不進一步膨脹現有類,它將不適合。那是當我決定在嘗試添加更多功能之前需要重構的時候(更新了希望澄清的問題)。 – 2010-07-16 12:36:48

+0

啊,好吧......是的,設計一個系統的方式可以擴展到不可預見的功能,這一直是一個很大的挑戰。我想這就是閱讀書籍不會讓你太過分(大部分)都會歸結爲經驗的東西之一。 – Mene 2010-07-17 22:49:31

0

不幸的是,TDD的支持者並沒有提出足夠的話,這讓人們嘗試TDD然後放棄它。

我所做的就是我所說的「高級測試」,它包含避免單元測試和專門進行高級測試(我們可以稱之爲「集成測試」)。它工作得很好,我避免了你提到的(非常重要的)問題。我前一段時間寫了一篇文章吧:

http://www.hardcoded.net/articles/high-level-testing.htm

祝你好運與TDD,不要輕言放棄。

+1

-1,因爲單元測試非常重要,非常有價值。高級測試告訴你出了什麼問題 - 這也是非常有價值的 - 但是單元測試告訴你出了什麼問題。不要沒有他們。 – 2010-07-16 13:14:07

+1

但是接下來發生的事情是,單元測試成爲一種責任,因爲它們使得重構耗費更多的時間。當發生這種情況時,你變得不太容易重構。那很糟。 – 2010-07-16 13:28:44

+1

如果你讓他們單元測試只成爲一種責任。重構實際上是我在做大量單元測試時做的更多的自信。是的,你可能有突破測試了一段時間,但可以在菲利普介紹的方式來避免,或者是你只是想當然而工作的重構和查看測試的回落到「綠色」一個接一個,有時很多很多。 – 2010-07-16 13:35:04

2

我想評論接受的答案,但我目前的聲望不允許我。所以這裏是一個新的答案。

TDD說:

創建一個測試失敗。編碼一點。通過測試。

它堅持以微小的步驟編碼(特別是在開始時)。將TDD視爲您爲構建程序而執行的連續重構的系統驗證。如果你採取的步驟太大,你的重構將失去控制。

+0

但我在我所有的測試合格(除了我剛剛寫的最後一個)的位置,但我並不滿意代碼的結構,它並不會輕易讓我實現了一個測試。之後,我執行的重構變得很糟糕。 – 2010-07-23 12:23:19

0

對於TDD連續迴歸測試用例也是必要的。因此Continuos與Coverage工具的整合(如上所述)是必要的。因此,很小的變化(即重構)可以輕鬆地迴歸,並且是否可以輕鬆找到任何遺漏的代碼路徑。

此外,我覺得如果以前沒有寫測試,時間不應該浪費在考慮是否編寫測試。測試應該立即寫入。