2013-03-26 78 views
1

在我的辦公室裏,除了主要負責與文件系統(DB等)交互的類的集成測試之外,我們對單元測試的必要性還有爭議。除了數據庫,文件系統等的集成測試之外,還需要進行單元測試嗎?

我們的集成測試幾乎是單元測試,因爲測試對象根本不與其他對象交互。爲什麼我們稱之爲測試集成的唯一原因是真正的文件系統用於測試。並建議使測試類使用文件系統層組件,然後在測試中模擬它(因此我們將它們稱爲單元測試),並檢查與此組件的交互,而不是真正的文件系統結果。這種改變的必要性就是我們所討論的。來看


有一點我們有,就是單元測試是必需的,因爲:

  1. 編寫單元測試使代碼更好
  2. 有單元測試,你並不需要關心關於真正的文件系統和文件的副作用,出現在錯誤的位置
  3. 開發人員可以通過使測試的類使用文件系統模擬並設置適當的模擬預期來充分測試結果
  4. 可以e對被測試類的特定內部算法的模擬期望,因爲我們使用單元測試進行白盒測試

因此,必須始終爲這樣一個測試類寫入單元測試。爲了測試目的,文件系統層組件必須總是被該類使用。


另一個角度來看,是不需要的單元測試的那些專門文件系統交互的類特定邊緣的情況下,這是因爲:

  1. 這是不能夠適當地驗證,即一個測試只是通過簡單的模擬而不是真正的文件系統(或其完整的模擬)來實現。文件系統是如此復​​雜的組件,即:
    • 被測試的類可以以許多不同的方式工作,以實現成功的結果。模擬期望僅涵蓋了兩種可能的情況,所以單元測試錯誤地顯示了一個類能正確實現好的算法的錯誤,這與預期的不同。
    • 被測試的類可以以某種方式工作,通過模擬將其檢測爲成功的場景,而類仍然不會產生正確的結果。這可能是因爲在真正的文件系統中有相當複雜的原因。所有這些原因都不可能通過模擬來實現。
  2. 帶有模擬和期望的單元測試非常脆弱,因爲它與測試類的內部算法非常相關。並且測試在算法的正確變化上錯誤地失敗。
  3. 當類只有1-2個公用方法,並且只有依賴項是文件系統時,集成測試纔是適用於單元測試的完全替代方案。集成測試爲這種情況提供了與單元測試相同的好處 - 清晰的依賴關係,更易讀的代碼等。

因此,我們不需要使用文件系統嘲諷進行單元測試。它是脆弱的,對於這種特殊的課程來說並不準確。


所以,概括起來講,問題是:
是集成測試完全足夠具有不復雜的類,它有主要責任與文件系統(DB等工作的邊緣情況)?

集成單元測試這個類之間的唯一區別是,在單元測試文件系統模擬,將使用(類將是完全隔離的),而與集成測試中使用的真正的文件系統。

我將不勝感激,如果你可以添加引用經典書籍,或者可能的知名業內人的文章/演示,所以我們可以有一個非常強地支持所產生的結論。

+0

http://www.growing-object-oriented-software.com/這是我參考TDD的書籍之一,也許這會有所幫助。順便說一句,單元測試不需要測試每個分支,而是專注於測試行爲。 – 2013-03-26 05:42:14

+0

http://stackoverflow.com/questions/129036/unit-testing-code-with-a-file-system-dependency這是類似於這個SO的問題之一。 – 2013-03-26 05:45:33

+0

謝謝@NarendraPathai。我見過那張票,但是我也在尋找一些對一般採用的來源(書籍,文章等)的參考。 – 2013-03-26 16:48:39

回答

1

這裏的簡短答案是,你可以可以完全測試一個類與'集成'測試。最好的問題,雖然是應該你這樣做?

我想你上了掛了一個「單元測試」(無外部依賴性)和「集成測試」(有這樣的依賴)之間在定義上的區別。測試的目標是讓您相信您的代碼始終在工作,同時保持相關的成本降低信心。所以你的問題

是集成測試完全夠有沒有 複雜類的邊緣情況下,有主要的責任與文件系統 (DB等)的工作?

有些不完整。

我們討論的「單元」和「集成」之間區別最有用的部分是這樣的:單元測試編寫,維護和運行更容易,更便宜。

要編寫單元測試,您只需要知道代碼。如果單元測試失敗,您知道這是因爲代碼發生了變化。編寫集成測試需要設置依賴關係,例如創建具有特定內容的文件,將行插入數據庫等。如果集成測試失敗,則可能是您的代碼,或者它可能是您的依賴關係。由於這些原因和其他原因,集成測試更加複雜,因此成本高昂,無法創建,維護和運行。

增加的開支應該推動開發人員將業務邏輯和處理與外部系統交互的類封裝起來,以儘量減少所需的集成測試次數。業務邏輯可以用更便宜的單元測試來測試。

編輯

這可能是你的類具有複雜的邏輯本身是複雜的,因爲它必須處理底層對外依存度(即,有關文件系統)複雜的行爲。在這種情況下,嘲笑文件系統本身可能相當困難,並且它可能會更便宜/更容易使用正確設置的文件系統並編寫「集成」測試。

要牢記的重要一點就是您要實現的目標:以可接受的成本實現自信。如果「集成」測試足夠便宜,那麼很好。如果使用「單元」測試可以更便宜地獲得相同的信心,那就更好了。確切的組合取決於手頭的問題。

+0

謝謝@sharakan。我聽到你的意思,因此我在問題中加入了澄清,即班級沒有外部依賴關係。集成測試目前僅被稱爲「集成」,因爲它們使用真正的文件系統。與提出的單元測試的區別在於,通過一些文件系統對象來處理所有事情,這些對象在單元測試期間會被模擬。 – 2013-03-26 16:52:20

+0

該類沒有外部依賴性,但集成測試使用真正的文件系統?通過大多數定義,「一個真正的文件系統」*是一種外部依賴。 – sharakan 2013-03-26 17:49:18

+0

從您的編輯中,我認爲您所說的是被測試的類相當複雜,因爲底層文件系統的行爲很複雜,需要處理。這可能會改變成本/收益分析,我會更新我的答案。 – sharakan 2013-03-26 17:53:34

0

這將是優選具有文件系統或DB爲測試的一個已知的狀態。作爲一個例子,你不想讓測試失敗,因爲它試圖插入一個已經存在的記錄。此故障不是由於代碼而是由於數據庫問題。文件系統中可能會發生同樣的事情。但是,你應該寫出你能夠做到的最好的測試。如果你不能輕易地嘲笑文件系統或其他什麼,然後與它進行交互。只要認識到,如果測試失敗,它可能不是代碼的問題。

的ugle測試總比沒有更好的測試。 Testivus http://www.artima.com/weblogs/viewpost.jsp?thread=203994

現在,即使你有嘲弄的測試,--The方式,並不意味着你不應該有質量保證或某種形式的集成測試,以確保一切正確連接。我認爲單元測試用於驗證代碼的內部工作是否正確,集成測試告訴我所有的代碼都可以一起工作。

我不知道你用的是什麼語言,但對於PHPUnit的文檔提供了有關測試數據庫和文件系統的一些想法。

用模擬和期望單元測試是非常脆弱的,因爲它是非常 綁被測類的內部算法。並且測試 在對算法進行正確更改時錯誤地失敗。

對於使用mock進行測試,您不應該綁定到算法。所有你正在測試的是該課程的預期行爲。不是這樣做的。

+0

謝謝@Schleis。我聽到你。關於不與算法結合 - 我們經歷的是文件系統模擬是不可能的。文件系統是一個複雜的組件,因此在沒有事先知道算法的情況下沒有辦法正確地設置mock的期望,並期望像「位於/ foo/bar的文件被打開,某些特定內容被寫入該文件,文件被關閉,文件被複制到/ baz/bar等「。我們主要關注這種脆弱而不充分的期望。 – 2013-03-26 16:57:25

相關問題