2009-10-13 177 views
2

目前,我的開發過程流程是這樣的:使用集成測試練習BDD - 我是否也需要單元測試?

  1. 我描述了預期的行爲作爲一個集成測試使用WebRat
  2. 我寫的Ruby on Rails的代碼來提供這種行爲使用,所以通過測試
  3. 我重構,以確保測試仍然通過在過程結束
  4. 我寫的下一個集成測試

在我看來,通過DEFI我的集成測試正在測試我可以創建的每個模型,控制器和視圖。實際上,我是否因爲不寫單元測試而錯過任何東西?

回答

2

你有任何rake任務嗎?自定義capistrano代碼?克龍方法?一個API? Monkeypatches?如何Flex或iPhone應用程序集成?一個工作跑步者?

在一個典型的Rails應用程序中,有很多代碼不是由HTML UI執行的。所以不,除非你的應用程序非常簡單,否則webrat測試是不夠的。

+0

謝謝莎拉。 到目前爲止,沒有。這是一個簡單的網絡應用程序 - 故意簡單。 除非/直到我構建的代碼不是由HTML UI執行的,我猜WebRat就足夠了? 如果我最終構建的代碼不是由HTML UI執行的,我想某種集成測試(顯然不是WebRat)就足夠了?或者除了通過集成測試對其進行測試之外,是否真的需要單獨測試每個單元? – 2009-10-13 23:50:43

+0

這取決於你的目標。如果您使用測試作爲重構的安全網,或者在添加代碼時用作捕獲錯誤的方法,那麼您仍然需要單元測試。沒有一套測試可以測試所有的東西,所以是的,你會看起來像是多餘的測試。 – 2009-10-14 02:40:54

3

集成測試有助於驗證代碼的不同部分是否完美集成。它們可能涉及所有圖層並覆蓋所有代碼,但是......當集成測試失敗時,它會告訴您錯誤位於何處?我可能是錯的,但我不這麼認爲。這隻會告訴你某處存在問題。另一方面,當真正的單元測試(使用模擬或存根進行隔離寫入)失敗時,您確切知道問題所在的單元(這實際上是單元測試的目的,驗證單元實現預期行爲) 。換句話說,單元測試和集成測試都是有用的,但它們有不同的目的。

+0

或者,更好的是與短文分開編寫。 大約80-90%的時間測試期望值在接口運行時更可靠。如果一個方法的兩個實現採用相同的參數併爲所有可能的參數提供相同的返回值,那麼通常需要爲這兩種實現傳遞相同的一組測試。對於沒有期望的測試雙倍測試,測試通常會起作用,但對於模擬測試來說不會。 – 2009-10-24 20:57:01

+0

其他10-20%的時間通常是API調用或者帶有副作用的代碼,無論如何你都應該重構。 – 2009-10-24 20:58:10

+0

@鮑勃是正確的,我應該寫「孤立寫」。我會更新我的答案。嘲笑或存根(stub),只要測試是孤立編寫的(而且嘲笑被過度使用,恕我直言),我並不關心那麼多。 – 2009-10-24 21:03:51

8

我其實非常同情你的觀點。我喜歡黃瓜我喜歡RSpec - 並且我都使用它們,但並不總是使用相同的代碼。例如,我現在很少爲Rails控制器編寫RSpec示例,並且幾乎從不寫視圖規範。我的大多數控制器非常相似,並且不會偏離「庫存」控制器模式 - 這已經通過Rails自己的單元測試進行了充分測試。再次驗證同樣的行爲對於所花費的時間和嘲笑所有模型的麻煩並沒有太大的幫助。通過集成級別的Cucumber,我可以跳過這個嘲諷並獲得我正在尋找的基本驗證。大多數情況下,在黃瓜中查看測試的處理也要透明得多。 (然後我看到「富」等等。)

但是,這並不是說我不Rails中廣泛使用RSpec的。我將它用於我的邏輯所在的地方:模型,控制器過濾器和視圖助手。我也有幾個項目幾乎都是全部商業邏輯,例如,庫或API適配器對付複雜的第三方接口。對於那些我通常只使用RSpec並跳過黃瓜的人。

作爲一種啓發式的,我建議你應該強烈考慮編寫一個單元測試,任何時候任何的以下問題可以回答「是」:

  • 是我寫的代碼比平凡複雜?
  • 此代碼是否存在主要用於解答其他代碼?
  • 這是我重構(還沒有單元測試)的現有代碼嗎?
  • 我在這段代碼中發現了一個錯誤嗎? (如果是這樣,請在修復之前編寫一個單元測試,以免它再次潛入。)
  • 我是否必須考慮超過十秒才能實現此代碼的最優雅方式?
  • 我的Spidey感是否刺痛?

如果以上都不是,那麼也許你可以逃脫只是做集成測試。再次,有很多情況下,這是合理的。但是,如果您稍後遇到問題,請準備付出代價 - 並且該價格應包括在任何時候編寫單元測試(如果他們似乎需要)。

+0

+1以避免控制器和視圖上的規格。單元測試Web服務控制器調用,模型和'lib'中的東西,但是將其留給Cucumber。 – 2009-10-24 21:01:24