2009-02-05 116 views

回答

13

如果您的測試代碼連接到實際的數據庫並依賴於某些數據(或缺少數據)的存在以便測試通過,那麼這是一項集成測試。

我通常通過模擬出用於獲取實際數據的「數據訪問方法」組件,無論是JDBC連接還是Web服務代理或其他任何組件來測試類似的東西。在模擬中,你會說「什麼時候調用這個方法,返回這個」或者「確保這個方法被調用N次」,然後你告訴被測試的類使用模擬組件而不是真實組件。這就是「單元測試」,因爲您正在測試被測試類的行爲方式,在一個已經聲明其他組件將如何表現的封閉系統中。你已經完全隔離了待測試的類,並且可以確保你的測試結果不會變化並且依賴於另一個組件的狀態。

不確定你正在使用哪種語言/技術,但在Java世界中,您可以使用JMock,EasyMock等來達到此目的。

0

最有可能的單元測試...但這裏有一個模糊的線。這實際上取決於正在執行多少代碼 - 如果它包含在一個庫或類中,那麼它的單元測試(如果它跨越多個組件)則更像是一個集成測試。

0

我認爲應該在單元測試中完成。您沒有測試它可以連接到數據庫,或者您可以調用您的存儲過程...您正在測試代碼的行爲。

我可能是錯的,但這就是我的想法,除非有人給我一個理由,否則。

7

做你的測試,讓其他人花時間分類。

+4

我認爲這種差異很重要,因爲它可以幫助您決定如何編寫,誰應該編寫,應該在哪裏生存,何時應該運行以及如何處理故障。但這不是陷入困境的藉口。投了票。 – 2009-02-05 16:16:41

+0

瞭解什麼是集成測試和單元測試可以幫助您找到針對該特定任務的良好框架,工具或最佳實踐。這個問題很有用! – 2009-07-25 12:33:20

1

我相信,有可能作爲一個單元測試,沒有真正的數據庫測試。用mock/stub/fake object(更好的可視化PDF爲here)替代它,而不是使用真正的數據庫接口。

如果將它作爲一個單元測試證明過於困難,並且您無法重構測試它的代碼很容易,那麼您最好將其作爲集成測試進行編寫。它會運行得更慢,所以你可能無法在代碼改變之後運行所有的集成測試(不像單元測試,你可以每秒運行數百和數千),但只要它們定期運行(例如作爲持續整合),它們產生了一些價值。

5

有些人(包括我自己)對構成單元測試和集成測試的構成有嚴格的規定。

測試is not a unit test如果:

  • 它談論到數據庫
  • 它通過網絡
  • 倒是文件系統
  • 它不能在同一時間運行的任何通信你的其他單元測試
  • 你必須對你的環境做特殊的事情(比如編輯配置文件)來運行它

而可能是一種方式之間做出什麼單元測試將做您使用嘲諷例如,而不是任何真正的資源提供者的一個區別 - 文件系統,數據庫等

集成測試能被視爲系統/應用程序層非常耦合的測試,所以基本要素在單元中進行測試,系統互操作性是集成測試的重點。

儘管它仍然是一個灰色地帶,因爲人們經常可以指出某些例外情況,這些規則。

2

我認爲最重要的問題是「我在做什麼?」

在這種情況下,我認爲你應該是單元測試。模擬與數據庫對話的代碼並讓它返回可靠的結果(無行),這樣,當沒有行時,測試會檢查會發生什麼,而不會在數據庫返回數據庫中的任何內容時發生什麼測試。

絕對單元測試它!

[TestMethod] 
public void ForgotMyPassword_SendsAnEmail_WhenValidUserIsPassed() 
{ 
    var userRepository = MockRepository.GenerateStub<IUserRepository>(); 
    var notificationSender = MockRepository.GenerateStub<INotificationSender>(); 
    userRepository.Stub(x => x.GetUserByEmailAddressAndPassword("[email protected]", "secret")).Return(new User { Id = 5, Name = "Peter Morris" }); 

    new LoginController(userRepository, notificationSender).ResendPassword("[email protected]", "secret"); 

    notificationSender.AssertWasCalled(x => x.Send(null), 
     options => options.Constraints(Text.StartsWith("Changed"))); 
} 
0

這是一個單元測試,根據定義:您正在一個特定的路徑上檢驗的代碼的單個分離的元件

5

我的觀點是,你應該基於範圍分類的測試:

  • 單元測試可獨立運行 無需任何外部的依賴 (文件IO,網絡IO,數據庫, 外部Web服務)。
  • 一個集成測試可以觸摸外部系統。

如果測試需要一個真正的數據庫運行,然後將其稱爲集成測試,並保持它與單元測試分開。這很重要,因爲如果你混合集成和單元測試,而不是讓代碼更易維護。

混雜的測試意味着新開發人員可能需要整個外部依賴堆才能運行測試套件。想象一下,你想對與數據庫相關的一段代碼進行更改,但實際上並不需要數據庫的功能,如果你只需要一個數據庫來運行與該數據庫相關的測試,就會感到沮喪項目。

如果外部依賴很難模擬出來(例如,在DotNet中,如果您使用的是Rhino Mocks而外部類沒有接口),則創建一個接觸外部系統的薄包裝類。然後在單元測試中嘲笑這個包裝。你不應該需要一個數據庫來運行這個簡單的測試,所以不需要一個!

10

我認爲有更多的時間浪費在爭論什麼是單位,什麼是集成測試而不是價值增加。

我不在乎。讓我用一種不同的方式:如果我正在測試它,我會看到兩種方法來實現 - 假數據庫返回零行,或者實際連接到沒有選擇數據的數據庫。我可能會開始測試什麼是最簡單和最簡單的實現 - 如果它足夠快,我可以得到有意義的反饋。然後我會考慮其他的,如果我需要它跑得更快或認爲會有一些優勢。

例如,我可能會開始連接到我工作的實際測試數據庫。但是,如果軟件需要與許多不同的數據庫一起工作 - Oracle,PostGres,MySQL,SQL服務器和數據庫,或者如果測試數據庫在工作中因爲「刷新」而關閉很多,我可能會寫'純/單元'測試完全孤立存在。

在我年老的時候,我更喜歡使用'面向開發人員'和'面向客戶'這兩個詞,並進行更有意義的測試。我發現廣泛使用像「單位」這樣的術語,然後得到一個定義,這會導致人們做一些事情,比如嘲笑文件系統或者嘲笑getter和setter - 這些我認爲是無益的。

我相信這強烈;我之前已經介紹過了。

http://www.google.com/url?sa=t&source=web&oi=video_result&ct=res&cd=1&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DPHtEkkKXSiY&ei=9-wKSobjEpKANvHT_MEB&rct=j&q=heusser+GTAC+2007&usg=AFQjCNHOgFzsoVss50Qku1p011J4-UjhgQ

好運!讓我們知道怎麼回事!

相關問題