在大型應用程序中從JUnit 4遷移到JUnit 5

addtoany linkedin

寫的:李香凝

在Kinaxis,單元測試是我們開發過程中不可分割的一部分。當涉及到捕獲缺陷時,它通常是第一道防線。在我們的Promotion Manager web應用程序中,我們跨棧的所有層進行單元測試。我們的前端層是用React編寫的,所以我們使用了Jest和Enzyme,這兩個庫一起工作來測試單個組件的行為。這一層與封裝產品業務邏輯的RESTful API通信。在這裏,我們使用Java Spring框架以及JUnit和Mockito的組合進行測試。

雖然我們長期使用JUnit 4,但我們最近開始研究JUnit 5,也稱為JUnit Jupiter,以改進我們的單元測試。這個庫是對前一個庫的重大升級,因為它有更強大的功能,使我們的測試更容易實現和維護。

在本文中,我將介紹我們的遷移過程,我們實現了哪些特性,以及下一步的步驟。遷移可能很棘手,所以我們的過程中有很多涉及到閱讀JUnit 5文檔,以更深入地理解框架。

以下是我強烈推薦的一些參考資料万搏体育app官方平台:

https://junit.org/junit5/docs/current/user-guide/

https://www.baeldung.com/junit-5

嵌套的測試:https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested

參數化測試:https://www.baeldung.com/parameterized-tests-junit-5

第一步

有些遷移要麼全部,要麼沒有——更新版本號將導致所有舊代碼失效,迫使完全重寫。這可能是一個漫長而乏味的過程。幸運的是,JUnit 4和JUnit 5特性可以共存,甚至在相同的測試類中。我們需要做的就是將必要的JUnit 5依賴項添加到我們的依賴項文件中。例如,下麵是一個Maven POM文件的片段。它包括兩個核心JUnit Jupiter依賴項,其次是Mockito,最後是JUnit Vintage,以支持遺留的JUnit測試引擎。然後,一旦我們安裝了JAR文件,我們就可以開始集成新特性了。

  1. <依賴>
  2. < groupId >org.junit.jupiter< / groupId >
  3. < artifactId >junit-jupiter-engine< / artifactId >
  4. <版本> 5.5.2 > < /版本
  5. < >範圍測驗< / >範圍
  6. < / >的依賴
  7. <依賴>
  8. < groupId >org.junit.jupiter< / groupId >
  9. < artifactId >junit-jupiter-params< / artifactId >
  10. <版本> 5.5.2 > < /版本
  11. < >範圍測驗< / >範圍
  12. < / >的依賴
  13. <依賴>
  14. < groupId >org.mockito< / groupId >
  15. < artifactId >mockito-junit-jupiter< / artifactId >
  16. <版本>2.23.0> < /版本
  17. < >範圍測驗< / >範圍
  18. < / >的依賴
  19. <依賴>
  20. < groupId >org.junit.vintage< / groupId >
  21. < artifactId >junit-vintage-engine< / artifactId >
  22. <版本>5.5.2> < /版本
  23. < >範圍測驗< / >範圍
  24. < / >的依賴

JUnit 4引入了擴展,為測試類提供了額外的功能。這些擴展可以獨立創建,然後跨多個類使用。Spring類運行器就是這樣一個擴展。它允許我們在測試中利用Spring的應用程序上下文和依賴項注入。JUnit 5通過使用單個注釋@ExtendWith簡化了擴展的實現。

要使用更新後的SpringExtension @ExtendWith,應用程序必須至少使用Spring 5。我們目前使用的是Spring 4.2.5,這意味著在我們首先升級Spring之前,遷移任何使用Spring JUnit 4類運行器的類都是阻塞的。盡管有這個阻塞器,我們仍然能夠在一些不使用Spring類運行器的現有測試中實現新的JUnit特性。

讓我們來看看它們是什麼以及我們如何設置它們。


參數化測試

我們的應用程序處理大型數據集,不同數據類型之間的複雜關係反映在底層域模型中。因此,我們需要仔細的測試,以確保對模型的任何更改都不會影響現有的對象。假設我們有一個函數,它根據給定的數據類型操作對象。如果我們想要驗證每種類型的行為,我們需要模擬對象並多次調用函數。正因為如此,隨著代碼庫的增長,我們的測試變得越來越長(而且不必要!)。

現在,在JUnit 5中,使用參數化測試隻需要幾行代碼就可以完成這些重複調用。它們設置起來又快又容易,而且大大縮短了測試類的長度。在下麵的示例中,我們可以編寫一個斷言語句,該語句應用於參數流。

這些論點可以從幾個不同的方麵獲得。在這裏,我們使用@MethodSource注釋從函數中提供一係列參數。當測試運行時,它被視為單個測試,但是如果一組參數失敗,斷言錯誤將確切地告訴我們是哪一組參數導致了失敗。

示例1.1 -使用方法源進行參數化測試。我們已經將員工類型抽象到一個單獨的方法中,這樣我們就可以對每種類型運行相同的斷言:

私有靜態流<參數>employeeParamSource(){

返回流。

參數。(員工。收銀員“01”,12),

參數。(員工。股票“2”,10),

參數。(員工。經理“03”,2

);


@ParameterizedTest

@MethodSource“employeeParamSource”

公共空間testGetNumStoreEmployees(員工employeeTypeString storeId, Integer numEmployees) {

為了(storeService.getNumEmployees (employeeTypestoreId)

.compareTo (expectedValue)是(numEmployees)

嵌套的測試

我們的邏輯最重的層自然有許多與之相關的測試。我們的一個測試類有3000多行代碼,隨著我們不斷地增加它,它變得越來越難處理了。我們研究了幾個不同的選項,將其分解為更易於管理的塊。我們可以為密切相關的測試創建單獨的類。JUnit 5提供的另一個選項是@Nested注釋。在內部類中使用時,它允許我們創建一組可以獨立運行的新測試。

為什麼我們要在單獨的類上使用@Nested ?如果我們的測試是嵌套的,那麼它們同樣(如果不是更詳細的話)冗長,但是這裏最大的優點是我們可以利用來自外部類的共享依賴項,並在我們的嵌套測試中使用它們。我們還可以為每個內部類設置特定的模擬數據,為我們編寫測試的方式提供了更大的靈活性。

例1.2 -嵌套測試類。外部類測試EmployeeDto,而內部類測試一個包含員工信息的CSV對象:

EmployeeDtoTest {

私人EmployeeDtoemployeeDto

@BeforeEach

無效設置(){

employeeDtoEmployeeDto (“愛麗絲”,員工。收銀員


@Nested

EmployeeDtoCsvTest {

私人EmployeeDto.CsvcsvObject

@BeforeEach

無效設置(){

csvObjectEmployeeDto.Csv (employeeDto

@Test

無效testGetEmployee(){

assertequal“愛麗絲,收銀員”csvObject.getEmployeeInfo ())

使用@Nested的一個注意事項是,內部類必須是非靜態的,而參數化測試的方法源函數必須是私有靜態的。這意味著如果我們想在嵌套類中使用參數化測試,我們需要使用其他選項中的一個來提供參數。

完成遷移

開發大型企業應用程序的最大挑戰之一是平衡特性工作和技術債務。我們的團隊也一樣;我們很容易被與客戶相關的工作搞得不知所措,而犧牲了代碼庫的健康和維護。全麵JUnit 5遷移的主要障礙是Spring遷移,我們知道這將是一項艱巨的任務,因為它需要對我們的整個應用程序進行重大更改。

我們發現,循序漸進地集成升級提供了一種更安全的選擇。因為測試不是麵向用戶的,它給了我們更多的自由來玩新功能和嚐試不同的東西。這也意味著我們不必為了適應移植而打亂我們的開發周期。一旦我們升級了Spring,我們就可以一次遷移剩下的幾個測試。

到目前為止,我們以一種特別的方式這樣做。我們遵循了一般的原則,即修改特定代碼段的開發人員負責遷移相應的測試類。這有助於在我們的團隊中分發關於JUnit 5的知識,因為每個人都以某種方式對遷移做出了貢獻。

一旦我們遷移了所有剩餘的測試,我們就可以安全地刪除JUnit Vintage依賴項。我們可以通過運行所有測試套件並驗證它們通過而沒有任何錯誤來確保一切都按預期工作。

我們認識到部分遷移可能不適合所有的主要升級。然而,考慮到JUnit 4和JUnit 5可以同時使用,一個緩慢、漸進的過程可以降低出錯的風險。我們可能會回顧使用JUnit 5的經驗,看看我們可以從未來的遷移中吸取什麼教訓。在那之前,團隊期待著完成到JUnit 5的遷移,並探索它的全部潛力。

作者:
Shannon Lee是Kinaxis的前軟件工程師。她目前是安大略省多倫多的一名軟件工程師。

留下一個回複

讓博客更新

通過電子郵件更新博客文章:

Eloqua webform