JUnit 5 –基础
JUnit 5是適用于Java的下一代單元測試框架,具有許多有趣的功能,包括嵌套測試,參數(shù)化測試,新的擴(kuò)展API或Java 8支持。
本文展示了JUnit 5的基本概念,包括測試生命周期,參數(shù)注入和斷言(基本,超時(shí)和異常)。
文獻(xiàn)資料
首先,我認(rèn)為JUnit 5文檔很棒。 它不僅包含全面的框架文檔,還包含許多示例,包括許多示例。 學(xué)習(xí)JUnit 5時(shí)請(qǐng)不要錯(cuò)過文檔: http : //junit.org/junit5/docs/current/user-guide/
依存關(guān)系
首先,JUnit 5需要Java 8才能運(yùn)行。 最后。 這帶來了在測試中使用Lambda表達(dá)式的可能性,并使它們更加簡潔(Lambda表達(dá)式主要用于斷言中)。 其次,JUnit 5由按JUnit平臺(tái),JUnit Jupiter和JUnit Vintage分組的多個(gè)工件組成。 這聽起來可能很嚇人,但是如今使用Maven或Gradle之類的工具根本不是問題,要開始使用,您實(shí)際上只需要一個(gè)依賴項(xiàng)。 Gradle的基本配置如下所示:
buildscript {ext {junitPlatformVersion = '1.0.1'junitJupiterVersion = '5.0.1'}repositories {mavenCentral()}dependencies {classpath "org.junit.platform:junit-platform-gradle-plugin:${junitPlatformVersion}"} }apply plugin: 'java' apply plugin: 'org.junit.platform.gradle.plugin'sourceCompatibility = 1.8repositories {mavenCentral() }dependencies { testRuntime("org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}") }task wrapper(type: Wrapper) {gradleVersion = '4.1' }JUnit 5測試類和方法
在測試類(從org.junit.jupiter.api導(dǎo)入)中使用的常見測試注釋是:
- @BeforeAll –在測試類中的所有方法之前執(zhí)行
- @BeforeEach –在測試類中的每個(gè)測試方法之前執(zhí)行
- @Test –實(shí)際測試方法
- @AfterEach –在測試環(huán)境中的每個(gè)測試方法之后執(zhí)行
- @AfterAll –在測試過程中的所有方法之后執(zhí)行
其他基本但有用的注釋:
- @DisplayName –測試類或方法的自定義顯示名稱
- @Disabled –禁用測試類或方法
- @RepeatedTest –用測試方法制作測試模板
- @Tag –標(biāo)記測試類或方法以進(jìn)一步選擇測試
一個(gè)基本的例子:
import org.junit.jupiter.api.*;@DisplayName("JUnit5 - Test basics") class JUnit5Basics {@BeforeAllstatic void beforeAll() {System.out.println("Before all tests (once)");}@BeforeEachvoid beforeEach() {System.out.println("Runs before each test");}@Testvoid standardTest() {System.out.println("Test is running");}@DisplayName("My #2 JUnit5 test")@Testvoid testWithCustomDisplayName() {System.out.println("Test is running");}@DisplayName("Tagged JUnit5 test ")@Tag("cool")@Testvoid tagged() {System.out.println("Test is running");}@Disabled("Failing due to unknown reason")@DisplayName("Disabled test")@Testvoid disabledTest() {System.out.println("Disabled, will not show up");}@DisplayName("Repeated test")@RepeatedTest(value = 2, name = "#{currentRepetition} of {totalRepetitions}")void repeatedTestWithRepetitionInfo() {System.out.println("Repeated test");}@AfterEachvoid afterEach() {System.out.println("Runs after each test");} }注意,測試類和方法不必是公共的 ,它們可以是包私有的 。
測試執(zhí)行生命周期
在JUnit 5中,默認(rèn)情況下會(huì)為測試類中的每個(gè)測試方法創(chuàng)建一個(gè)新的測試實(shí)例。 可以使用類級(jí)別@TestInstance注釋來調(diào)整此行為:
import org.junit.jupiter.api.*;@TestInstance(TestInstance.Lifecycle.PER_CLASS) @DisplayName("JUnit5 - Test lifecycle adjustments") class JUnit5PerClassLifecycle {private Object first = new Object();private Object second;@BeforeAllvoid beforeAll() {this.second = this.first;System.out.println("Non static before all.");}@BeforeEachvoid beforeEach() {Assertions.assertEquals(first, second);}@Testvoid first() {Assertions.assertEquals(first, second);}@Testvoid second() {Assertions.assertEquals(first, second);}@AfterAllvoid afterAll() {System.out.println("Non static after all.");}@AfterEachvoid afterEach() {Assertions.assertEquals(first, second);} }在PER_CLASS模式下,將為所有測試創(chuàng)建單個(gè)測試實(shí)例,并且@BeforeAll和@AfterAll方法不再需要是靜態(tài)的。
參數(shù)解析
測試和回調(diào)方法現(xiàn)在可以采用org.junit.jupiter.api.TestInfo , org.junit.jupiter.api.RepetitionInfo或org.junit.jupiter.api.TestReporter類的參數(shù)。
另外,由于使用了非常簡單但功能強(qiáng)大的JUnit 5擴(kuò)展API,因此在方法中解析自定義參數(shù)只需提供自己的org.junit.jupiter.api.extension.ParameterResolver實(shí)現(xiàn)即可。
class JUnit5BuiltInParameterResolution {@BeforeAllstatic void beforeAll(TestInfo testInfo) {System.out.println("Before all can take parameters. Started: " + testInfo.getDisplayName());}@BeforeAllstatic void beforeAll(TestReporter testReporter) {testReporter.publishEntry("myEntry", "myValue");}@BeforeAllstatic void beforeAll(TestInfo testInfo, TestReporter testReporter) {testReporter.publishEntry("myOtherEntry", testInfo.getDisplayName());}@BeforeEachvoid beforeEach(TestInfo testInfo) {}@Testvoid standardTest(TestInfo testInfo) {}@DisplayName("Repeated test")@RepeatedTest(value = 2, name = "#{currentRepetition} of {totalRepetitions}")void repeatedTest(RepetitionInfo repetitionInfo) {System.out.println("Repeated test - " + repetitionInfo.toString());}@AfterAllstatic void afterAll() {}@AfterAllstatic void afterAll(TestInfo testInfo) {}@AfterEachvoid afterEach() {} }斷言
JUnit 5帶有許多標(biāo)準(zhǔn)斷言,可以在org.junit.jupiter.api.Assertions類中找到。
基本斷言
基本主張是: assertEquals , assertArrayEquals , assertSame , assertNotSame , assertTrue , assertFalse , assertNull , assertNotNull , assertLinesMatch , assertIterablesMatch
例:
@Test void basicAssertions() {// arrangeList<String> owners = Lists.newArrayList("Betty Davis", "Eduardo Rodriquez");// assertassertNotNull(owners);assertSame(owners, owners);assertFalse(owners::isEmpty); // Lambda expressionassertEquals(2, owners.size(), "Found owner names size is incorrect");assertLinesMatch(newArrayList("Betty Davis", "Eduardo Rodriquez"), owners);assertArrayEquals(new String[]{"Betty Davis", "Eduardo Rodriquez"}, owners.toArray(new String[0])); }斷言所有
Assertions.assertAll斷言所有提供的可執(zhí)行文件均不會(huì)引發(fā)異常:
Assertions.assertAll(() -> Assertions.assertNotNull(null, "May not be null"),() -> Assertions.assertTrue(false, "Must be true") );上面將報(bào)告多個(gè)失敗:
org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures)May not be null ==> expected: not <null>Must be true注意:您可能想閱讀有關(guān)JUnit 4和AssertJ中的替代方法的信息-http: //blog.codeleak.pl/2015/09/assertjs-softassertions-do-we-need-them.html
超時(shí)斷言
使用超時(shí)斷言來驗(yàn)證未超過任務(wù)的執(zhí)行時(shí)間。 超時(shí)斷言有兩種: assertTimeout和assertTimeoutPreemptively 。 都拿兩個(gè)
- 同步執(zhí)行任務(wù),等待任務(wù)完成,然后聲明超時(shí):
- 異步執(zhí)行任務(wù)(在新線程中),到超時(shí)時(shí)中止執(zhí)行:
異常斷言
JUnit 5內(nèi)置的assertThrows獲取預(yù)期的異常類型作為第一個(gè)參數(shù),而可執(zhí)行文件(功能接口)則可能將異常作為第二個(gè)參數(shù)。 如果未引發(fā)任何異?;蚱渌愋偷漠惓?#xff0c;則該方法將失敗。 該方法返回異常本身,該異常可用于進(jìn)一步的聲明:
@Test void assertException() {// arrangeExecutable throwingExecutable = () -> {throw new RuntimeException("Unexpected error!");};// act and assertRuntimeException thrown = Assertions.assertThrows(RuntimeException.class, throwingExecutable::execute, "???");Assertions.assertAll(() -> Assertions.assertEquals("Unexpected error!", thrown.getMessage()),() -> Assertions.assertNotNull(thrown.getCause())); }注意:您可能想閱讀有關(guān)JUnit 4中的替代方法的信息-http: //blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html
摘要
JUnit 5具有許多功能。 在本文中,僅演示了基礎(chǔ)知識(shí),但這足以讓您開始編寫第一個(gè)JUnit 5測試。
也可以看看
- 使用JUnit 5進(jìn)行更清潔的參數(shù)化測試– http://blog.codeleak.pl/2017/06/cleaner-parameterized-tests-with-junit-5.html
翻譯自: https://www.javacodegeeks.com/2017/10/junit-5-basics-2.html
總結(jié)
以上是生活随笔為你收集整理的JUnit 5 –基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想笔记本电脑音频驱动(笔记本电脑音频驱
- 下一篇: 关于总决赛