高效的企业测试-集成测试(3/6)
本系列的這一部分將展示如何通過代碼級以及系統級集成測試來驗證我們的應用程序。
(代碼級)集成測試
集成測試一詞有時在不同的上下文中使用不同。 根據Wikipedia的定義,我指的是在代碼級別上驗證多個組件之間相互作用的測試。 通常,集成測試利用嵌入式容器或其他模擬環境來測試應用程序的子集。 諸如Spring Tests,Arquillian,CDI-Unit之類的測試技術使編寫測試變得容易,并且易于將各個類注入測試類以在測試執行期間進行直接交互。
下面顯示了使用CDI-Unit運行器的集成測試的偽代碼示例:
測試方案可以輕松注入和模擬依賴項,并可以在測試方法中訪問它們。
由于嵌入式測試技術需要花一些時間才能啟動,因此嵌入式集成測試通常對整個測試執行時間有最大的負面影響。 根據我的經驗,許多項目會復制并粘貼現有的測試方案,并以每種測試類都會重新啟動應用程序或其一部分的方式運行它們。 隨著時間的推移,這會大大增加構建的周轉時間,以至于開發人員將無法獲得快速的反饋。
盡管這些類型的測試可以驗證“管道”的正確性,但是API和注釋是否被正確使用,它們并不是測試業務邏輯的最有效方法。 尤其是在微服務應用程序中,集成測試不能提供最終的信心,尤其是端點和持久性的集成是否會像生產環境中那樣完全。 最終,在映射JSON對象,處理HTTP請求或將對象持久保存到數據存儲的方式上,總會有微小的差異。
問題總是,我們的測試應該真正驗證什么。 我們是否正在驗證框架,框架的正確用法或整個應用程序的正確行為?
代碼級集成測試很好地工作,可以快速反饋開發人員在連接框架時是否犯了一些粗心的錯誤。 在這種情況下,一些單個測試用例不能驗證業務邏輯,而只是能夠以冒煙測試的方式啟動應用程序,就可以提高開發效率。
但是,如果我們的應用程序沒有以過于復雜的方式利用我們的企業框架,例如使用自定義限定符,CDI擴展或自定義范圍,那么對代碼級集成測試的需求就會減少。 由于我們有使用系統測試來捕獲相同類型錯誤的方法,還有許多其他方法,因此我通常不鼓勵開發人員編寫過多的代碼級集成測試。 集成測試確實使在代碼級別上連接多個組件變得容易,但是,可以使用不同的方法,例如用例測試,而這些方法并不會增加啟動時間。
由于集成測試技術通常會啟動或部署到容器中,因此它們通常會定義自己的生命周期,因此很難將其集成到更大的畫面中。 如果開發人員想要制定優化的開發工作流程,則需要以一種模式運行應用程序,該模式可以在不同生命周期中熱重新加載更改,然后針對正在運行的應用程序快速執行集成測試,而通過這些類型的集成測試很難做到這一點。 ,因為他們通常會啟動自己的應用程序。 有一些技術可以改善這一點,例如Quarkus及其集成測試。 盡管如此,一種更簡單,更靈活的方法是將測試方案與整個應用程序上下文的生命周期分開。
與(嵌入式)應用程序生命周期糾纏在一起的測試還使得很難在多個范圍內重用測試方案,因為它們通常需要使用特定的運行程序或其他約束來執行。 在很多情況下,重用測試場景(定義測試邏輯部分的代碼)在不同的范圍內簡化了增強測試套件的過程,例如用于用例測試,負載測試或系統測試。 如果這些案例對如何執行沒有太多限制,例如與哪個測試運行程序一起使用,重用它們,即將它們復制到其他位置并交換使用的委托或組件的實現,則變得更加簡單。 正如您將在以下內容中看到的,有很多有效的方法可以完全驗證我們的應用程序,尤其是對于更復雜的項目。
系統測試
在微服務世界中,我們的應用程序越來越多地與其他資源(例如外部系統,數據庫,隊列或消息代理)集成在一起,并且通常包括不太復雜的業務邏輯。 話雖如此,從外部角度驗證我們系統的行為至關重要,也就是說,以與生產中其他組件相同的方式與我們的應用程序進行交互。
系統測試通過使用常規接口(例如HTTP,gRPC,JMS或WebSockets)來驗證已部署應用程序的行為。 它們是在環境中執行的,在該環境中,被測試應用程序的部署和配置與生產環境完全相同,通常會模擬或模擬外部系統。 測試方案可以與模擬的外部系統進行交互,以進一步控制方案并驗證行為。 容器技術,模擬服務器和嵌入式數據庫可以在這方面提供很多幫助。
通常,系統測試可以與實現分離,因此可以使用各種技術編寫。 盡管使用與應用程序項目相同的技術通常是有意義的,因為開發人員已經熟悉它,例如,還可以將JUnit與HTTP客戶端(例如JAX-RS)一起使用。
我們應該注意不要將系統測試與實際實現耦合在一起,也就是說,不要重復使用類定義或導入共享模塊。 盡管這在項目中試圖減少重復,但實際上增加了在應用程序界面更改時錯過回歸的可能性,有時是偶然的。 例如,如果生產代碼和測試代碼都更改了對象序列化為JSON的方式,則在重用類定義時(例如“垃圾回收,垃圾回收”),API合同中可能不需要的更改將不會被捕獲。 ”)。 因此,通常建議將系統測試保存在單獨的項目中,這些項目使用它們自己的,可能會簡化的類定義,或者以其他方式強制測試類不會重復使用生產代碼。 實現確實應驗證通信是否按預期進行,例如檢查預期的HTTP狀態代碼。 如果生產行為發生了不必要的變化,則系統測試項目及其行為不會被修改,并將檢測到合同中的變化。
由于系統測試方案可能很快變得相當復雜,因此我們需要關注可維護性和測試代碼質量。 我們將在稍后對此進行仔細研究,但是一般而言,建議構造特殊的委托以控制和與模擬的外部系統進行通信,以及創建測試數據。
對于更復雜的設置而言,至關重要的是定義冪等系統測試,以驗證特定行為,而與當前狀態無關。 我們應避免創建僅適用于全新的空系統或需要按特定順序執行的測試方案。 實際的業務用例通常也在運行時間更長的系統上執行,并同時執行。 如果我們在系統測試中達到相同的隔離級別,則可以避免測試與特定的前提條件或執行順序糾纏在一起,并且可以并行運行它們,也可以針對可以持續運行超過一次試運行。 這是建立有效的本地工作流以及潛在地出于不同目的重用測試方案定義的前提。
為了使環境保持相似,問題在于生產的外觀如何以及在本地開發或持續交付管道中如何使生產盡可能接近。 通常,容器的出現使實現該目標變得更加容易。 如果我們的應用程序在容器中運行,我們可以通過多種方式在本地執行它們,或者通過外殼腳本,Docker Compose,測試容器啟動它們,我們將在稍后介紹它們,或者甚至運行成熟的Kubernetes或OpenShift簇。 在持續交付管道中,我們理想地以與生產相同的方式部署到環境并對其進行測試,即使用相同技術和配置的集群或環境,例如單獨的Kubernetes集群或命名空間。
根據系統的復雜性和本地開發工作流程,我們可以在系統測試執行中或通過單獨的工具從外部管理已部署應用程序的生命周期。 根據經驗,從外部管理環境(即通過單獨的機制啟動環境并對其進行冪等測試),可以更快地執行,為我們的工作流程提供更大的靈活性,并且最終也更易于管理。 一種非常方便的方法是定義用于包裝實際命令的shell腳本,例如如何啟動Docker容器,如何設置Docker compose,如何啟動Kubernetes和應用YAML文件,否則,只需在該腳本上執行腳本即可。開發會議開始。 由于系統測試具有獨立的生命周期并連接到已經在運行的環境,因此它們可以非常快速地運行。 專用測試環境和本地設置均可實現。 在本地設置復雜的環境聽起來像是改變某些行為并驗證我們的更改的大轉變,但是,具有熱部署技術的現代開發工具可幫助我們保持周期的Swift。 我們可以立即修改被測應用程序的行為,然后重新執行測試用例,這也可以非常快速地運行。
這種方法為我們提供了非常快速的反饋,但經過了適當的驗證,因為我們是針對實際的應用程序界面而不是仿真進行測試。 但是,至關重要的是我們必須保持設置的可維護性,以使復雜性可管理。
在本系列文章的下一部分中,我們將介紹有效的開發工作流程以及測試代碼質量的重要性以及如何實現測試保持可維護性。
翻譯自: https://www.javacodegeeks.com/2019/09/efficient-enterprise-testing-integration-tests-3-6.html
總結
以上是生活随笔為你收集整理的高效的企业测试-集成测试(3/6)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中九刷机工具集app(99手机刷机工具)
- 下一篇: 使用测微计收集应用程序指标