maven配置junit5_JUnit 5和Selenium –改善项目配置
maven配置junit5
Selenium是一組支持瀏覽器自動(dòng)化的工具和庫(kù),主要用于Web應(yīng)用程序測(cè)試。 Selenium的組件之一是Selenium WebDriver,它提供客戶(hù)端庫(kù),JSON有線協(xié)議(與瀏覽器驅(qū)動(dòng)程序進(jìn)行通信的協(xié)議)和瀏覽器驅(qū)動(dòng)程序。 Selenium WebDriver的主要優(yōu)點(diǎn)之一是,它受所有主要編程語(yǔ)言的支持,并且可以在所有主要操作系統(tǒng)上運(yùn)行。
在帶有Selenium WebDriver的JUnit 5的這一部分–教程中,您將了解JUnit 5的其他功能,這些功能將通過(guò)并行運(yùn)行測(cè)試,配置測(cè)試順序和創(chuàng)建參數(shù)化測(cè)試來(lái)幫助您減少測(cè)試的執(zhí)行時(shí)間。
您還將學(xué)習(xí)如何利用Selenium Jupiter功能,例如通過(guò)系統(tǒng)屬性進(jìn)行測(cè)試執(zhí)行配置,單個(gè)瀏覽器會(huì)話(huà)測(cè)試以加快測(cè)試執(zhí)行速度或捕獲測(cè)試中的屏幕截圖。 最后,您將學(xué)習(xí)如何將AssertJ庫(kù)添加到您的項(xiàng)目。
關(guān)于本教程
您正在閱讀帶有Selenium WebDriver的JUnit 5的第三部分-教程 。
本教程中的所有文章:
- 第1部分– 從頭開(kāi)始設(shè)置項(xiàng)目–使用JUnit 5和Jupiter Selenium進(jìn)行Gradle
- 第2部分– 使用Selenium內(nèi)置的PageFactory實(shí)現(xiàn)Page Object Pattern
- 第3部分– 改進(jìn)項(xiàng)目配置–并行執(zhí)行測(cè)試,測(cè)試執(zhí)行順序,參數(shù)化測(cè)試,AssertJ等
本教程的源代碼可以在Github上找到
使用JUnit 5并行測(cè)試執(zhí)行
JUnit 5帶有內(nèi)置的并行測(cè)試執(zhí)行支持。
以下命令將并行運(yùn)行TodoMvcTests的測(cè)試方法:
./gradlew clean test --tests *TodoMvcTests -Djunit.jupiter.execution.parallel.enabled= true -Djunit.jupiter.execution.parallel.mode. default =concurrent構(gòu)建成功,在執(zhí)行過(guò)程中,您應(yīng)該注意到兩個(gè)Chrome瀏覽器實(shí)例正在運(yùn)行。 在此運(yùn)行中,所有測(cè)試的執(zhí)行時(shí)間減少到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提示:有關(guān)更多選項(xiàng),請(qǐng)查閱文檔: https : //junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
使用JUnit 5測(cè)試執(zhí)行順序
自動(dòng)化測(cè)試應(yīng)能夠獨(dú)立運(yùn)行且無(wú)特定順序,并且測(cè)試結(jié)果不應(yīng)依賴(lài)于先前測(cè)試的結(jié)果。 但是在某些情況下,可以證明測(cè)試執(zhí)行的特定順序。
默認(rèn)情況下,在JUnit 5中,測(cè)試方法的執(zhí)行在構(gòu)建之間是可重復(fù)的,因此具有確定性,但是該算法是故意不明顯的(作為庫(kù)狀態(tài)的作者)。 幸運(yùn)的是,可以使用內(nèi)置方法定購(gòu)器或通過(guò)創(chuàng)建自定義定購(gòu)器來(lái)調(diào)整執(zhí)行順序以滿(mǎn)足我們的需求。 我們將使用@Order批注提供測(cè)試方法的排序,并使用@TestMethodOrder注釋類(lèi),以指示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 }在本文中閱讀有關(guān)JUnit 5中測(cè)試執(zhí)行順序的更多信息: https : //blog.codeleak.pl/2019/03/test-execution-order-in-junit-5.html
Selenium Jupiter的單個(gè)瀏覽器會(huì)話(huà)
您可能已經(jīng)注意到,對(duì)于TodoMvcTests類(lèi)中的每個(gè)測(cè)試, TodoMvcTests啟動(dòng)一個(gè)新的Chrome瀏覽器實(shí)例,并在每個(gè)測(cè)試之后將其關(guān)閉。 此行為導(dǎo)致整個(gè)套件的執(zhí)行花費(fèi)了相當(dāng)多的時(shí)間(上一次執(zhí)行需要27秒)。 Selenium Jupiter附帶了一個(gè)方便的類(lèi)級(jí)別注釋,可以更改此行為。 @SingleSession批注會(huì)更改行為,以便在所有測(cè)試之前初始化瀏覽器實(shí)例一次,并在所有測(cè)試之后關(guān)閉瀏覽器實(shí)例。
要應(yīng)用@SingleSession我們需要稍微修改測(cè)試類(lèi),并將驅(qū)動(dòng)程序?qū)ο笞⑷氲綐?gòu)造函數(shù)中,而不是注入到@BeforeEach方法中。 我們還需要注意每次測(cè)試的正確狀態(tài)。 這可以通過(guò)清除@AfterEach方法中@AfterEach存儲(chǔ)的本地存儲(chǔ)來(lái)完成。 我還創(chuàng)建了一個(gè)字段driver ,該字段driver保留了所有測(cè)試中使用的驅(qū)動(dòng)程序?qū)ο髮?shí)例。
我使用注入到@BeforeEach和@AfterEach方法中的驅(qū)動(dòng)程序測(cè)試了@SingleSession ,但似乎這沒(méi)有按預(yù)期方式工作,并且每次執(zhí)行新測(cè)試時(shí),都會(huì)創(chuàng)建一個(gè)新的驅(qū)動(dòng)程序?qū)嵗?我相信這是庫(kù)的另一個(gè)設(shè)計(jì)缺陷。
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(); }當(dāng)我們執(zhí)行測(cè)試時(shí),我們可以觀察到執(zhí)行所有測(cè)試的時(shí)間大大減少了:
./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提示:如果您希望從選定的類(lèi)中運(yùn)行測(cè)試,則可以使用Gradle測(cè)試任務(wù)隨附的測(cè)試過(guò)濾。 例如,此命令將僅運(yùn)行TodoMvcTests類(lèi)中的測(cè)試: ./gradlew clean test --tests *.todomvc.TodoMvcTests
并行執(zhí)行單個(gè)瀏覽器會(huì)話(huà)測(cè)試
請(qǐng)注意,如果您現(xiàn)在嘗試使用JUnit 5并行性并行執(zhí)行測(cè)試,則測(cè)試將失敗。 在并行執(zhí)行中,每個(gè)方法都需要單獨(dú)的驅(qū)動(dòng)程序?qū)嵗?#xff0c;并啟用@SingleSession我們?yōu)樗袦y(cè)試共享一個(gè)實(shí)例。 為了解決這個(gè)問(wèn)題,我們需要運(yùn)行測(cè)試配置并行執(zhí)行,以便頂級(jí)類(lèi)并行運(yùn)行,但方法在同一線程中。
只需復(fù)制TodoMvcTests類(lèi),然后嘗試以下命令:
./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在執(zhí)行過(guò)程中,您應(yīng)該看到3個(gè)瀏覽器正在運(yùn)行并在終端中輸出,類(lèi)似于以下內(nèi)容:
<===========--> 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的通用驅(qū)動(dòng)程序配置
在當(dāng)前測(cè)試中,我們將ChromeDriver直接注入到測(cè)試類(lèi)中。 但是在某些情況下,我們希望對(duì)注入的驅(qū)動(dòng)程序有更多的控制,而我們寧愿注入WebDriver(接口)并稍后決定應(yīng)該注入哪個(gè)驅(qū)動(dòng)程序?qū)嵗?我們還需要更改storageCleanup()方法,因?yàn)橥ㄓ肳ebDriver不提供直接的localStorage訪問(wèn):
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()" ); }現(xiàn)在,要在運(yùn)行時(shí)更改瀏覽器類(lèi)型,我們需要調(diào)整sel.jup.default.browser config屬性。
配置JUnit 5和Selenium Jupiter的常見(jiàn)方法之一是通過(guò)Java系統(tǒng)屬性。 可以使用屬性文件以編程方式完成此操作,也可以使用-D開(kāi)關(guān)將屬性直接傳遞給JVM。 為了確保在執(zhí)行Gradle時(shí)傳遞給JVM的屬性在測(cè)試中可用,我們需要修改build.gradle ,如下所示:
test { // Make system properties available in tests systemProperties System.getProperties() useJUnitPlatform() testLogging { events "passed" , "skipped" , "failed" } }到目前為止,當(dāng)您運(yùn)行./gradlew clean test -Dprop=value類(lèi)的命令時(shí),該屬性prop將在測(cè)試中可用。
通過(guò)上述更改,我們可以選擇瀏覽器類(lèi)型來(lái)運(yùn)行測(cè)試:
./gradlew clean test --tests *TodoMvcTests -Dsel.jup. default .browser=firefox使用Selenium Jupiter保存屏幕截圖
Selenium Jupiter允許在測(cè)試結(jié)束時(shí)保存屏幕截圖-始終或僅在失敗時(shí)保存。 您還可以自定義輸出目錄和格式。
./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提示:有關(guān)更多選項(xiàng),請(qǐng)查閱文檔: https : //bonigarcia.github.io/selenium-jupiter/#screenshots
使用JUnit 5進(jìn)行參數(shù)化測(cè)試
參數(shù)化單元測(cè)試的總體思路是對(duì)不同的測(cè)試數(shù)據(jù)運(yùn)行相同的測(cè)試方法。 要在JUnit 5中創(chuàng)建參數(shù)化測(cè)試,請(qǐng)使用@ParameterizedTest注釋測(cè)試方法,并提供該測(cè)試方法的參數(shù)源。 有幾種可用的參數(shù)來(lái)源,包括:
- @ValueSource –提供對(duì)文字值數(shù)組(即短褲,整數(shù),字符串等)的訪問(wèn)。
- @MethodSource –提供對(duì)從工廠方法返回的值的訪問(wèn)
- @CsvSource –從一個(gè)或多個(gè)提供的CSV行中讀取逗號(hào)分隔值(CSV)
- @CsvFileSource –用于加載逗號(hào)分隔值(CSV)文件
在下一個(gè)示例中,我們將使用存儲(chǔ)在src/test/resources目錄中的以下CSV:
todo;done Buy the milk; false Clean up the room; true Read the book; false為了在測(cè)試中使用上述CSV文件,我們需要使用@ParameterizedTest注釋(而不是@Test )對(duì)測(cè)試進(jìn)行注釋,然后使用@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文件中的每個(gè)記錄都有兩個(gè)字段: name和done 。 在上述測(cè)試中,僅使用待辦事項(xiàng)的名稱(chēng)。 但是我們當(dāng)然可以使測(cè)試復(fù)雜一點(diǎn),并同時(shí)使用這兩個(gè)屬性:
@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); }請(qǐng)注意,同一測(cè)試類(lèi)別/
了解更多關(guān)于這篇文章中參數(shù)的測(cè)試: https://blog.codeleak.pl/2017/06/cleaner-parameterized-tests-with-junit-5.html也經(jīng)歷了JUnit 5文檔: https://開(kāi)頭的JUnit .org / junit5 / docs / current / user-guide /#writing-tests-parameterized-tests
使用AssertJ更好的斷言
JUnit 5具有許多內(nèi)置的斷言,但是當(dāng)真正的工作開(kāi)始時(shí),您可能需要的遠(yuǎn)遠(yuǎn)超出了JUnit 5所能提供的。 在這種情況下,我建議使用AssertJ庫(kù)。 AssertJ AssertJ是一個(gè)Java庫(kù),提供了豐富的斷言集,真正有用的錯(cuò)誤消息,提高了測(cè)試代碼的可讀性,并且設(shè)計(jì)為在您喜歡的IDE中非常容易使用。
AssertJ的一些功能:
- 對(duì)許多Java類(lèi)型的流利斷言,包括日期,集合,文件等。
- SoftAssertions(類(lèi)似于JUnit 5的assertAll)
- 復(fù)雜領(lǐng)域比較
- 可以輕松擴(kuò)展–自定義條件和自定義斷言
要在項(xiàng)目中使用AssertJ,我們需要向build.gradle添加一個(gè)依賴(lài)build.gradle :
testCompile( 'org.assertj:assertj-core:3.13.2' )首先,我們需要靜態(tài)導(dǎo)入org.assertj.core.api.Assertions.*并使用帶有assertThat方法的代碼完成: assertThat(objectUnderTest).
例如,您將編寫(xiě)assertThat(todoMvc.getTodosLeft()).isEqualTo(3); 使用AssertJ而不是assertEquals(3, todoMvc.getTodosLeft()); 在普通的JUnit 5或assertThat(todoMvc.todoExists(readTheBook)).isTrue()而不是assertTrue(todoMvc.todoExists(readTheBook)) 。
使用復(fù)雜類(lèi)型甚至更好:
todoMvc.createTodos(buyTheMilk, cleanupTheRoom, readTheBook); assertThat(todoMvc.getTodos()) .hasSize( 3 ) .containsSequence(buyTheMilk, cleanupTheRoom, readTheBook);請(qǐng)?jiān)L問(wèn)官方文檔以了解有關(guān)AssertJ的更多信息: https ://assertj.github.io/doc/
提示:閱讀有關(guān)將AssertJ與JUnit 5集成的更多信息: https ://blog.codeleak.pl/2017/11/junit-5-meets-assertj.html
摘要
在本文中,我介紹了如何利用JUnit 5的內(nèi)置功能來(lái)提高項(xiàng)目配置的速度,但不僅限于速度。 您還了解了如何利用某些Selenium Jupiter功能來(lái)改進(jìn)項(xiàng)目。
看起來(lái)可能已經(jīng)很多了,JUnit 5和Selenium Jupiter都提供了更多功能。 查看兩個(gè)項(xiàng)目文檔,并找出對(duì)當(dāng)前或?qū)?lái)的項(xiàng)目有用的其他內(nèi)容:
- 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
總結(jié)
以上是生活随笔為你收集整理的maven配置junit5_JUnit 5和Selenium –改善项目配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 有范是什么意思 有范儿是什么意思
- 下一篇: Eclipse系列的隐藏宝藏– 2019