2010-07-14 106 views
4

容器內測試通常與使用模擬對象進行測試相反。但是,由於模擬對象只是模仿真實對象的行爲,因此容器內測試不是真正在真實環境中測試系統的唯一方法嗎?容器內測試與模擬對象進行集成測試

作爲容器內部測試和模擬對象的部分替代方案,Spring提供了TestContext框架,它可以很好地初始化Spring,而無需啓動實際的應用程序容器(在我的情況下爲Web應用程序服務器)。然而,這是有限的方法,因爲它只初始化Spring特有的功能,而不支持應用程序服務器特定的功能。所以你不能測試一切。另外,因爲它與用於真正web執行的默認WebApplicationContext不是100%相同,所以這種方法有點不合理嗎?它不好嗎?

對於容器內測試,至少有Cactus(過時),Jeeunit(一個非常小的項目)和JBoss Arquillian(仍然是α,但看起來很有希望)。我沒有看到任何這些項目被廣泛使用,那麼容器內測試有什麼不好的地方?容器內測試經常提到的主要缺點是執行速度慢。但是,當在持續集成環境中運行並且在相對較小的項目中運行時,這應該不成問題。

總結:我們應該進行容器內外測試還是爲什麼?使用模擬對象或替代初始化機制(如在Spring TestContext中)來進行集成測試會感覺不好嗎?

附註:我最近問了一下categorization of integration test,這可能是相關的。

回答

3

但是,由於模擬對象只是模擬真實對象的行爲,而不是容器內測試真正在真實環境中測試系統的唯一方法嗎?

我認爲簡單的答案是肯定的,但是......我認爲你的「整合測試分類」問題是非常相關的。單位和集成測試均爲雖然服務功能不同,但重要。

單元測試與代碼密切相關,如果啓動和運行速度非常快,開發人員應該經常運行代碼,並且通常會使用mock來實現高度的代碼。這個想法是測試有問題的代碼,而不是它的依賴或集成點。將單元測試全部放在容器中的問題是,它們運行得不那麼頻繁,否則會浪費太多開發時間。

我們已經在另一個項目中的其他項目的其他地方隔離了我們的容器內/集成測試,並且依賴於代碼項目。它們旨在儘可能地模仿生產配置。這些測試需要更長的時間進行設置,運行時間更長,並且更有用於像cruisecontrol這樣的運行。它們是手工操作的,特別是當我們在發佈時或者在開發穩定之後。當我要去吃午餐或開會時,通常我會啓動集成測試。當一個集成測試發現一個bug時,我們嘗試編寫一個單元測試,這個單元測試也演示了這個嘲諷的錯誤 - 這往往很難並且是不可能的。

我們通常會在單元測試中進行一些小的容器內測試,以確保彈簧接線正常工作或測試一些基本功能,但其他集成測試在另一個項目中完成。

所有這一切說,兩者之間並沒有明顯的差別。有時我們會移動處理大量數據的單元測試,並花費很長時間進行集成測試,有時集成測試運行得足夠快,並且足夠有價值,可與代碼一起使用。

+0

我非常好地運行了容器外的單元測試。其實,我不明白你爲什麼要運行「幾個小容器內單元測試」來測試「彈簧佈線」和東西?也許你在那裏弄錯了,你的意思是「一對小容器內集成測試*」嗎?另外,我的理解是否正確:如果對運行時配置進行更改,則必須將該設置複製到集成測試項目中?您如何實際運行/初始化容器內測試?在某種框架的幫助下可能? – 2010-07-14 13:13:59

+0

我編輯了該部分。我的意思是我們在我們的單元測試集合中進行了幾次集成測試,以確保所有的Spring接線都能正常工作。所有配置文件都帶有代碼 - 我們不會將任何配置複製到集成項目中。集成項目與生產代碼共享相同的包路徑,因此可以加載所有相同的src/main/resource(我們使用mvn)configs。 – Gray 2010-07-14 13:33:00

2

我想說我們應該做在容器內和外容器測試。我在測試容器時發現的主要問題是自動化所有內容的工作量更大。您可以通過Spring的集成測試支持獲得一些更便宜的勝利,但我們不應該欺騙自己,因爲這涵蓋了部署容器中測試的所有內容。我發現他們可以在Spring集成測試中扮演一個角色,但我更傾向於使用虛假/存根服務和罐頭結果來進行集成和容器內測試(這是我的「 d呼叫系統測試)。

如果您不確定嘲笑與st what之間的區別是什麼,請查看Martin Fowler article

+0

你在容器內測試中使用了什麼庫?讓我想到的是,每個容器內測試框架(Cactus,jeeunit,Arquillian)似乎都爲不同的技術(如CDI,EJB,Servlet等)提供了特定的支持。難怪支持所有這些需要一些額外的配置: /感謝這篇文章的指針,我不得不承認,我在這種情況下經驗很少。 – 2010-07-14 13:25:46