整合測試
能夠執行一些整合測試,而無需部署到您的應用程式伺服器或連線到其他企業基礎架構,這一點非常重要。這樣做可讓您測試諸如:
-
Spring IoC 容器 Context 的正確佈線。
-
使用 JDBC 或 ORM 工具的資料存取。這可以包括諸如 SQL 陳述式的正確性、Hibernate 查詢、JPA 實體對應等等。
Spring Framework 在 spring-test
模組中提供對整合測試的一流支援。實際 JAR 檔案的名稱可能包含發行版本,也可能採用長 org.springframework.test
形式,具體取決於您從何處取得它(請參閱關於相依性管理的章節以取得說明)。此程式庫包含 org.springframework.test
套件,其中包含用於與 Spring 容器進行整合測試的寶貴類別。此測試不依賴應用程式伺服器或其他部署環境。此類測試的執行速度比單元測試慢,但比依賴於部署到應用程式伺服器的等效 Selenium 測試或遠端測試快得多。
單元和整合測試支援以註解驅動的 Spring TestContext Framework 的形式提供。TestContext Framework 與正在使用的實際測試框架無關,這允許在各種環境(包括 JUnit、TestNG 和其他環境)中對測試進行檢測。
以下章節概述了 Spring 整合支援的高階目標,本章的其餘部分將重點介紹專門的主題:
整合測試的目標
Spring 的整合測試支援具有以下主要目標:
-
管理測試之間的 Spring IoC 容器快取。
-
提供適合整合測試的 交易管理。
-
提供 Spring 專用基底類別,以協助開發人員編寫整合測試。
接下來的幾個章節將描述每個目標,並提供指向實作和組態詳細資訊的連結。
Context 管理和快取
Spring TestContext Framework 提供 Spring ApplicationContext
實例和 WebApplicationContext
實例的一致載入,以及這些 Context 的快取。對載入的 Context 進行快取的支援非常重要,因為啟動時間可能會成為問題,這不是因為 Spring 本身的開銷,而是因為 Spring 容器實例化的物件需要時間來實例化。例如,具有 50 到 100 個 Hibernate 對應檔案的專案可能需要 10 到 20 秒才能載入對應檔案,並且在每個測試 Fixture 中執行每個測試之前產生該成本會導致整體測試執行速度變慢,從而降低開發人員的生產力。
測試類別通常宣告 XML 或 Groovy 組態中繼資料的資源位置陣列(通常在類別路徑中),或用於組態應用程式的元件類別陣列。這些位置或類別與 web.xml
或其他生產部署組態檔案中指定的位置或類別相同或相似。
預設情況下,一旦載入,組態的 ApplicationContext
將針對每個測試重複使用。因此,設定成本僅在每個測試套件產生一次,並且後續測試執行速度會快得多。在此 Context 中,「測試套件」一詞表示在同一個 JVM 中執行的所有測試,例如,針對給定專案或模組從 Ant、Maven 或 Gradle 建置執行的所有測試。在不太可能發生的測試損壞應用程式 Context 並需要重新載入的情況下(例如,透過修改 Bean 定義或應用程式物件的狀態),可以組態 TestContext Framework 以在執行下一個測試之前重新載入組態並重建應用程式 Context。
請參閱 TestContext Framework 的 Context 管理 和 Context 快取。
測試 Fixture 的相依性注入
當 TestContext Framework 載入您的應用程式 Context 時,它可以選擇性地使用相依性注入來組態您的測試類別實例。這提供了一種方便的機制,可透過使用應用程式 Context 中的預先組態 Bean 來設定測試 Fixture。這裡的一個強大優勢是,您可以在各種測試情境中重複使用應用程式 Context(例如,用於組態 Spring 管理的物件圖、交易 Proxy、DataSource
實例等),從而避免為個別測試案例重複複雜的測試 Fixture 設定。
作為範例,考慮一個情境,其中我們有一個類別 (HibernateTitleRepository
) 實作 Title
網域實體的資料存取邏輯。我們想要編寫整合測試來測試以下區域:
-
Spring 組態:基本上,與
HibernateTitleRepository
Bean 的組態相關的所有內容是否正確且存在? -
Hibernate 對應檔案組態:是否一切都對應正確,並且是否已設定正確的延遲載入設定?
-
HibernateTitleRepository
的邏輯:此類別的組態實例是否如預期般執行?
請參閱使用 TestContext Framework 進行測試 Fixture 的相依性注入。
交易管理
存取真實資料庫的測試中一個常見問題是它們對持久性儲存狀態的影響。即使您使用開發資料庫,狀態的變更也可能會影響未來的測試。此外,許多操作(例如插入或修改持久性資料)無法在交易之外執行(或驗證)。
TestContext Framework 解決了這個問題。預設情況下,Framework 會為每個測試建立並回滾交易。您可以編寫可以假設交易存在的程式碼。如果您在測試中呼叫交易 Proxy 物件,它們會根據其組態的交易語意正確運作。此外,如果測試方法在為測試管理的交易內執行時刪除選定表格的內容,則預設情況下會回滾交易,並且資料庫會還原到執行測試之前的狀態。交易支援是透過使用在測試的應用程式 Context 中定義的 PlatformTransactionManager
Bean 提供給測試的。
如果您希望交易提交(不常見,但有時在您希望特定測試填入或修改資料庫時很有用),您可以告訴 TestContext Framework 使用 @Commit
註解來導致交易提交而不是回滾。
請參閱使用 TestContext Framework 進行交易管理。
整合測試的支援類別
Spring TestContext Framework 提供了幾個 abstract
支援類別,可簡化整合測試的編寫。這些基底測試類別提供了進入測試框架的明確定義的 Hook,以及方便的實例變數和方法,可讓您存取:
-
ApplicationContext
,用於執行明確的 Bean 查詢或測試 Context 的整體狀態。 -
JdbcTemplate
,用於執行 SQL 陳述式來查詢資料庫。您可以使用此類查詢來確認資料庫狀態在執行資料庫相關應用程式程式碼之前和之後的狀態,並且 Spring 確保此類查詢在與應用程式程式碼相同的交易範圍內執行。當與 ORM 工具結合使用時,請務必避免 誤報。
此外,您可能想要建立自己的自訂應用程式範圍的父類別,其中包含特定於您的專案的實例變數和方法。
請參閱 TestContext Framework 的支援類別。