maven配置junit5_JUnit 5和Selenium –改善项目配置
maven配置junit5
Selenium是一組支持瀏覽器自動化的工具和庫,主要用于Web應用程序測試。 Selenium的組件之一是Selenium WebDriver,它提供客戶端庫,JSON有線協議(與瀏覽器驅動程序進行通信的協議)和瀏覽器驅動程序。 Selenium WebDriver的主要優點之一是,它受所有主要編程語言的支持,并且可以在所有主要操作系統上運行。
在帶有Selenium WebDriver的JUnit 5的這一部分–教程中,您將了解JUnit 5的其他功能,這些功能將通過并行運行測試,配置測試順序和創建參數化測試來幫助您減少測試的執行時間。
您還將學習如何利用Selenium Jupiter功能,例如通過系統屬性進行測試執行配置,單個瀏覽器會話測試以加快測試執行速度或捕獲測試中的屏幕截圖。 最后,您將學習如何將AssertJ庫添加到您的項目。
關于本教程
您正在閱讀帶有Selenium WebDriver的JUnit 5的第三部分-教程 。
本教程中的所有文章:
- 第1部分– 從頭開始設置項目–使用JUnit 5和Jupiter Selenium進行Gradle
- 第2部分– 使用Selenium內置的PageFactory實現Page Object Pattern
- 第3部分– 改進項目配置–并行執行測試,測試執行順序,參數化測試,AssertJ等
本教程的源代碼可以在Github上找到
使用JUnit 5并行測試執行
JUnit 5帶有內置的并行測試執行支持。
以下命令將并行運行TodoMvcTests的測試方法:
./gradlew clean test --tests *TodoMvcTests -Djunit.jupiter.execution.parallel.enabled= true -Djunit.jupiter.execution.parallel.mode. default =concurrent構建成功,在執行過程中,您應該注意到兩個Chrome瀏覽器實例正在運行。 在此運行中,所有測試的執行時間減少到10秒:
> Task :test pl.codeleak.demos.selenium.todomvc.TodoMvcTests > createsTodo() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > createsTodosWithSameName() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > togglesAllTodosCompleted() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > togglesTodoCompleted() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > clearsCompletedTodos() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > editsTodo() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > removesTodo() PASSED BUILD SUCCESSFUL in 10s 4 actionable tasks: 4 executed提示:有關更多選項,請查閱文檔: https : //junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
使用JUnit 5測試執行順序
自動化測試應能夠獨立運行且無特定順序,并且測試結果不應依賴于先前測試的結果。 但是在某些情況下,可以證明測試執行的特定順序。
默認情況下,在JUnit 5中,測試方法的執行在構建之間是可重復的,因此具有確定性,但是該算法是故意不明顯的(作為庫狀態的作者)。 幸運的是,可以使用內置方法定購器或通過創建自定義定購器來調整執行順序以滿足我們的需求。 我們將使用@Order批注提供測試方法的排序,并使用@TestMethodOrder注釋類,以指示JUnit 5方法已排序。
@ExtendWith (SeleniumExtension. class ) @SingleSession @TestMethodOrder (MethodOrderer.OrderAnnotation. class ) @DisplayName ( "Managing Todos" @DisplayName "Managing Todos" ) class TodoMvcTests { @Test @Order ( 1 ) @DisplayName ( "Creates Todo with given name" ) void createsTodo() { } @Test @Order ( 2 ) @DisplayName ( "Creates Todos all with the same name" @DisplayName "Creates Todos all with the same name" ) void createsTodosWithSameName() { } // rest of the methods omitted for readability }在本文中閱讀有關JUnit 5中測試執行順序的更多信息: https : //blog.codeleak.pl/2019/03/test-execution-order-in-junit-5.html
Selenium Jupiter的單個瀏覽器會話
您可能已經注意到,對于TodoMvcTests類中的每個測試, TodoMvcTests啟動一個新的Chrome瀏覽器實例,并在每個測試之后將其關閉。 此行為導致整個套件的執行花費了相當多的時間(上一次執行需要27秒)。 Selenium Jupiter附帶了一個方便的類級別注釋,可以更改此行為。 @SingleSession批注會更改行為,以便在所有測試之前初始化瀏覽器實例一次,并在所有測試之后關閉瀏覽器實例。
要應用@SingleSession我們需要稍微修改測試類,并將驅動程序對象注入到構造函數中,而不是注入到@BeforeEach方法中。 我們還需要注意每次測試的正確狀態。 這可以通過清除@AfterEach方法中@AfterEach存儲的本地存儲來完成。 我還創建了一個字段driver ,該字段driver保留了所有測試中使用的驅動程序對象實例。
我使用注入到@BeforeEach和@AfterEach方法中的驅動程序測試了@SingleSession ,但似乎這沒有按預期方式工作,并且每次執行新測試時,都會創建一個新的驅動程序實例。 我相信這是庫的另一個設計缺陷。
private final ChromeDriver driver; public TodoMvcTests(ChromeDriver driver) { this .driver = driver; this .todoMvc = PageFactory.initElements(driver, TodoMvcPage. class ); this .todoMvc.navigateTo(); } @AfterEach void storageCleanup() { driver.getLocalStorage().clear(); }當我們執行測試時,我們可以觀察到執行所有測試的時間大大減少了:
./gradlew clean test > Task :test pl.codeleak.demos.selenium.todomvc.TodoMvcTests > editsTodo() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > togglesTodoCompleted() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > createsTodo() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > removesTodo() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > togglesAllTodosCompleted() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > createsTodosWithSameName() PASSED pl.codeleak.demos.selenium.todomvc.TodoMvcTests > clearsCompletedTodos() PASSED pl.codeleak.demos.selenium.todomvc.SeleniumTest > projectIsConfigured(ChromeDriver) PASSED BUILD SUCCESSFUL in 9s 3 actionable tasks: 3 executed提示:如果您希望從選定的類中運行測試,則可以使用Gradle測試任務隨附的測試過濾。 例如,此命令將僅運行TodoMvcTests類中的測試: ./gradlew clean test --tests *.todomvc.TodoMvcTests
并行執行單個瀏覽器會話測試
請注意,如果您現在嘗試使用JUnit 5并行性并行執行測試,則測試將失敗。 在并行執行中,每個方法都需要單獨的驅動程序實例,并啟用@SingleSession我們為所有測試共享一個實例。 為了解決這個問題,我們需要運行測試配置并行執行,以便頂級類并行運行,但方法在同一線程中。
只需復制TodoMvcTests類,然后嘗試以下命令:
./gradlew clean test --tests *TodoMvcTests -Djunit.jupiter.execution.parallel.enabled= true -Djunit.jupiter.execution.parallel.mode. default =same_thread -Djunit.jupiter.execution.parallel.mode.classes. default =concurrent在執行過程中,您應該看到3個瀏覽器正在運行并在終端中輸出,類似于以下內容:
<===========--> 87 % EXECUTING [3s] > :test > 0 tests completed > :test > Executing test pl.codeleak.demos.selenium.todomvc.MoreTodoMvcTests > :test > Executing test pl.codeleak.demos.selenium.todomvc.EvenMoreTodoMvcTests > :test > Executing test pl.codeleak.demos.selenium.todomvc.TodoMvcTestsSelenium Jupiter的通用驅動程序配置
在當前測試中,我們將ChromeDriver直接注入到測試類中。 但是在某些情況下,我們希望對注入的驅動程序有更多的控制,而我們寧愿注入WebDriver(接口)并稍后決定應該注入哪個驅動程序實例。 我們還需要更改storageCleanup()方法,因為通用WebDriver不提供直接的localStorage訪問:
public TodoMvcTests(WebDriver driver) { this .driver = driver; this .todoMvc = PageFactory.initElements(driver, TodoMvcPage. class ); this .todoMvc.navigateTo(); } @AfterEach void storageCleanup() { ((JavascriptExecutor) driver).executeScript( "window.localStorage.clear()" ); }現在,要在運行時更改瀏覽器類型,我們需要調整sel.jup.default.browser config屬性。
配置JUnit 5和Selenium Jupiter的常見方法之一是通過Java系統屬性。 可以使用屬性文件以編程方式完成此操作,也可以使用-D開關將屬性直接傳遞給JVM。 為了確保在執行Gradle時傳遞給JVM的屬性在測試中可用,我們需要修改build.gradle ,如下所示:
test { // Make system properties available in tests systemProperties System.getProperties() useJUnitPlatform() testLogging { events "passed" , "skipped" , "failed" } }到目前為止,當您運行./gradlew clean test -Dprop=value類的命令時,該屬性prop將在測試中可用。
通過上述更改,我們可以選擇瀏覽器類型來運行測試:
./gradlew clean test --tests *TodoMvcTests -Dsel.jup. default .browser=firefox使用Selenium Jupiter保存屏幕截圖
Selenium Jupiter允許在測試結束時保存屏幕截圖-始終或僅在失敗時保存。 您還可以自定義輸出目錄和格式。
./gradlew clean test --tests *TodoMvcTests -Dsel.jup. default .browser=firefox -Dsel.jup.screenshot.at.the.end.of.tests= true -Dsel.jup.screenshot.format=png -Dsel.jup.output.folder=/tmp提示:有關更多選項,請查閱文檔: https : //bonigarcia.github.io/selenium-jupiter/#screenshots
使用JUnit 5進行參數化測試
參數化單元測試的總體思路是對不同的測試數據運行相同的測試方法。 要在JUnit 5中創建參數化測試,請使用@ParameterizedTest注釋測試方法,并提供該測試方法的參數源。 有幾種可用的參數來源,包括:
- @ValueSource –提供對文字值數組(即短褲,整數,字符串等)的訪問。
- @MethodSource –提供對從工廠方法返回的值的訪問
- @CsvSource –從一個或多個提供的CSV行中讀取逗號分隔值(CSV)
- @CsvFileSource –用于加載逗號分隔值(CSV)文件
在下一個示例中,我們將使用存儲在src/test/resources目錄中的以下CSV:
todo;done Buy the milk; false Clean up the room; true Read the book; false為了在測試中使用上述CSV文件,我們需要使用@ParameterizedTest注釋(而不是@Test )對測試進行注釋,然后使用@CsvFileSource注釋指向該文件:
@ParameterizedTest @CsvFileSource (resources = "/todos.csv" , numLinesToSkip = 1 , delimiter = ';' ) @DisplayName ( "Creates Todo with given name" ) void createsTodo(String todo) { todoMvc.createTodo(todo); assertSingleTodoShown(todo); }CSV文件中的每個記錄都有兩個字段: name和done 。 在上述測試中,僅使用待辦事項的名稱。 但是我們當然可以使測試復雜一點,并同時使用這兩個屬性:
@ParameterizedTest (name = "{index} - {0}, done = {1}" ) @CsvFileSource (resources = "/todos.csv" , numLinesToSkip = 1 , delimiter = ';' ) @DisplayName ( "Creates and optionally removes Todo with given name" ) void createsAndRemovesTodo(String todo, done) { boolean done) { todoMvc.createTodo(todo); assertSingleTodoShown(todo); todoMvc.showActive(); assertSingleTodoShown(todo); if (done) { todoMvc.completeTodo(todo); assertNoTodoShown(todo); todoMvc.showCompleted(); assertSingleTodoShown(todo); } todoMvc.removeTodo(todo); assertNoTodoShown(todo); }請注意,同一測試類別/
了解更多關于這篇文章中參數的測試: https://blog.codeleak.pl/2017/06/cleaner-parameterized-tests-with-junit-5.html也經歷了JUnit 5文檔: https://開頭的JUnit .org / junit5 / docs / current / user-guide /#writing-tests-parameterized-tests
使用AssertJ更好的斷言
JUnit 5具有許多內置的斷言,但是當真正的工作開始時,您可能需要的遠遠超出了JUnit 5所能提供的。 在這種情況下,我建議使用AssertJ庫。 AssertJ AssertJ是一個Java庫,提供了豐富的斷言集,真正有用的錯誤消息,提高了測試代碼的可讀性,并且設計為在您喜歡的IDE中非常容易使用。
AssertJ的一些功能:
- 對許多Java類型的流利斷言,包括日期,集合,文件等。
- SoftAssertions(類似于JUnit 5的assertAll)
- 復雜領域比較
- 可以輕松擴展–自定義條件和自定義斷言
要在項目中使用AssertJ,我們需要向build.gradle添加一個依賴build.gradle :
testCompile( 'org.assertj:assertj-core:3.13.2' )首先,我們需要靜態導入org.assertj.core.api.Assertions.*并使用帶有assertThat方法的代碼完成: assertThat(objectUnderTest).
例如,您將編寫assertThat(todoMvc.getTodosLeft()).isEqualTo(3); 使用AssertJ而不是assertEquals(3, todoMvc.getTodosLeft()); 在普通的JUnit 5或assertThat(todoMvc.todoExists(readTheBook)).isTrue()而不是assertTrue(todoMvc.todoExists(readTheBook)) 。
使用復雜類型甚至更好:
todoMvc.createTodos(buyTheMilk, cleanupTheRoom, readTheBook); assertThat(todoMvc.getTodos()) .hasSize( 3 ) .containsSequence(buyTheMilk, cleanupTheRoom, readTheBook);請訪問官方文檔以了解有關AssertJ的更多信息: https ://assertj.github.io/doc/
提示:閱讀有關將AssertJ與JUnit 5集成的更多信息: https ://blog.codeleak.pl/2017/11/junit-5-meets-assertj.html
摘要
在本文中,我介紹了如何利用JUnit 5的內置功能來提高項目配置的速度,但不僅限于速度。 您還了解了如何利用某些Selenium Jupiter功能來改進項目。
看起來可能已經很多了,JUnit 5和Selenium Jupiter都提供了更多功能。 查看兩個項目文檔,并找出對當前或將來的項目有用的其他內容:
- https://bonigarcia.github.io/selenium-jupiter/
- https://junit.org/junit5/
翻譯自: https://www.javacodegeeks.com/2019/12/junit-5-and-selenium-improving-project-configuration.html
maven配置junit5
總結
以上是生活随笔為你收集整理的maven配置junit5_JUnit 5和Selenium –改善项目配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有范是什么意思 有范儿是什么意思
- 下一篇: 匮怎么读什么意思 匮字简单介绍