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