2010-02-23 211 views
7

基本上我有兩個主要問題:如何進行單元測試?

  • 你究竟應該測試什麼?
  • 你怎麼做到的?

問題是我有幾個應用程序依賴於數據庫連接和/或通信應用程序,這意味着大多數測試用例都是集成測試(或者我認爲)。

大多數類是本身非常簡單,但是實現的通信協議,這是那些將是自動化測試有用的人,似乎可以很好地成爲「單元測試」的模式。

另一個例子。我爲消費者/生產者模式開發了帶有多線程支持的I管道結構。當一個線程讀取管道並發現它爲空時,它會阻塞,直到寫入者寫入管道。我應該使用單元測試來測試這個類嗎?

你如何決定單元測試?

編輯:我的意思是自動單元測試編寫單元測試。

回答

4

你單元測試你的代碼的單位。真正的問題是什麼構成一個單位?

在面向對象的環境中,單元是一個類。一個類,因爲一個對象的行爲隨着對象的狀態而變化,所以單獨測試一個方法不會得到最完整的結果。

首先你需要確定類的不變量。也就是說,對於班級的所有事例來說,這些事情總會是真的。例如。在Fraction類不變可能是分母!= 0

接下來,你需要確定每種方法的合同,也就是說,這些方法的前置和後置條件。

然後你爲每個可能出現的情況編寫測試。因此,對於單個課程,您最終可能會有許多測試方法來測試每種方法可能遇到的各種情況。在每次測試中,您都要確保該類的不變式保持不變,並且方法的合同永遠不會中斷。

在某些情況下,像您提供可能需要以測試你的類的條件,創造環境中的其他對象的例子。在這些情況下,你可以使用模擬對象。

+0

所以,即使你需要模擬其他對象或模擬外部事件或設備,它可以被認爲是一個單元測試和測試應該寫出來嗎? – 2010-02-23 23:22:38

+0

@Jorge Corboda是的。我想是這樣。很多像運行在容器中的代碼一樣的環境很難單獨測試。所以爲測試創建模擬對象被認爲是很好的做法。儘管測試代碼可以獨立運行,這一點很重要。 – 2010-02-23 23:55:47

+0

雖然從技術上來說,任何在被測單元(數據庫,文件系統等)之外具有依賴性的代碼測試都是集成測試。但是,這兩個術語可以交替使用,而且往往是相同的。 – ZombieSheep 2010-02-24 11:28:08

0

單元測試是測試整個單元的工作原理相同,因爲它改變之前一樣,在變化所做的改進。如果您正在更改一個模塊的窗口,那麼你測試模塊。這與測試每個模塊的系統測試相比。如果你的改變影響了很多模塊(不知道你的系統是如何設置的),那麼它應該得到一個系統測試。

+0

嗯,我的錯,我的意思是自動單元測試...就像你實際編碼的那個:) – 2010-02-23 23:20:29

1

您應該抽象的基礎設施問題(即從數據庫中檢索數據的代碼,代碼,做文件I/O等),這樣就可以存根/爲了嘲笑那些部分單元測試你的應用。然後,您將能夠針對您的基礎架構代碼編寫針對性/特定的測試以進行測試。你會發現自己創建更多的接口(在你的應用程序中似乎創建),並需要使用更好的面向對象原則(即。SOLID)以開發更具可測試性的應用程序。

我是在同一條船上一年前,你在,而且一本書,真的幫了我通過它(與實踐一些手一起)是The Art of Unit Testing by Roy Osherove

+0

我聽說過有關這方面的好東西...... – RSolberg 2010-02-24 00:20:18

1

單元測試的測試單位(即方法或功能)隔離,在一個專門的,受控制的環境。每個單元測試通過僅實例化執行一個測試所需的類,將它們置於已知狀態,然後調用要測試的方法並驗證結果,在自己的環境中創建。該驗證通過關於該方法的行爲(與其實現相反)的斷言完成。

對行爲進行驗證是非常重要的,因爲這樣可以在不中斷單元測試的情況下修改實現,因此使用單元測試作爲修改的安全網。

所有語言都有[至少]一個unit test framework,它們的作用是執行單元測試。有兩種編寫單元測試的方法:測試優先或最後測試。

測試優先也被稱爲Test-Driven Development。基本上,它需要三個步驟:

  1. 寫一個失敗的測試
  2. 寫只是足夠多的代碼,使之通過
  3. 重構代碼,把它清理乾淨(去除重複...)

TDD的支持者聲稱這導致了可測試的代碼,但事實上可能很難編寫單元測試,特別是當方法做了幾件事時。建議遵循單一責任原則。

關於管結構和通信協議例如,一些指引說 a test is not a unit test if

  • 它談論到數據庫
  • 它通過網絡
  • 通信倒是文件系統
  • ...

當某個線程讀取管道並找到 時,它會清空該塊,直到寫入器 寫入管道。我應該使用 單元測試來測試這個類嗎?

我將測試的類,但不阻擋讀方法,因爲我相信它是從阻擋調用操作系統的功能read()建立。

+0

TDD有一個非常*重要的步驟4 - 「確保重構後測試仍然通過」。顯而易見,但有時被忽視。 – ZombieSheep 2010-02-24 11:29:03

+0

同意這很重要 - 但它是重構的一部分,而不是TDD。 TDD週期是「紅色,綠色,重構」。 – philant 2010-02-24 13:54:38

相關問題