天天看點

Java單元測試工具JUnit 5新特性一覽Java單元測試工具JUnit 5新特性一覽

版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chszs/article/details/50662639

Java單元測試工具JUnit 5新特性一覽

作者:chszs,未經部落客允許不得轉載。經許可的轉載需注明作者和部落格首頁: http://blog.csdn.net/chszs

JUnit是最流行的開源Java單元測試工具,目前它的穩定版是4.12版。JUnit 4是2005年推出的,它基于Java 5的注釋、反射等特性開發,距今已經超過十年了,受目前Java 8以及Lambda表達式等的影響,JUnit團隊決定推出JUnit 5版。

目前JUnit 5已經推出了5.0.0 Alpha版,見:

https://t.co/Mb12F3WF4A

一、JUnit 5的更新情況

JUnit 5完全使用目前的Java 8重寫了所有代碼,是以JUnit 5的運作條件是Java 8環境。

JUnit 5允許在斷言中使用Lambda表達式,這個特性可以從開源的斷言庫AssertJ中可以看到。

AssertJ庫見:

http://joel-costigliola.github.io/assertj/

與JUnit 4不同,JUnit 5不再是單個庫,而是子產品化結構的集合,整個API分成了:自己的子產品、引擎、launcher、針對Gradle和Surefire的內建子產品。

JUnit團隊還發起了名為Open Test Alliance for the JVM的活動,見:

https://github.com/ota4j-team/opentest4j

JUnit 5的測試看上去與JUnit 4相同:同樣是建立類,添加測試方法,使用@Test注釋。但是,JUnit 5還提供了全新的一套注釋集合,而且斷言方法從JUnit 4的org.junit.Assert包移到了JUnit 5的org.junit.gen5.api.Assertions包。比如:

import org.junit.gen5.api.Assertions;
import org.junit.gen5.api.Test;
public class Test1 {
  @Test
  public void test()  {
    Assertions.assertEquals(3 * 6, 18);
    Assertions.assertTrue(5 > 4);
  }
}
           

二、JUnit 5斷言

JUnit 5的斷言方法與JUnit 4相似,斷言類提供了assertTrue、assertEquals、assertNull、assertSame以及相反的斷言方法。不同之處在于JUnit 5的斷言方法支援Lambda表達式。而且還有一個名為分組斷言(Grouped Assertions)的新特性。

分組斷言允許執行一組斷言,且會一起報告。要記得在JUnit 4中,我們被告誡不要在一個測試中放入多個斷言,以避免某些斷言沒有得到執行。現在,在JUnit 5中使用分組斷言就無需再顧慮這個避諱了。

對JUnit 4的另一個改進是斷言預期的異常。不再是以前那種把預期的異常類型放入@Test注釋,或者是用try-catch包裹代碼,JUnit 5使用assertThrows和equalsThrows斷言。下面看看斷言的例子:

public class Test2 {
  @Test
  public void lambdaExpressions() {
    // lambda expression for condition
    assertTrue(() -> "".isEmpty(), "string should be empty");
    // lambda expression for assertion message
    assertEquals("foo", "foo", () -> "message is lazily evaluated");
  }
  @Test
  public void groupedAssertions() {
    Dimension dim = new Dimension(800, 600);
    assertAll("dimension", 
        () -> assertTrue(dim.getWidth() == 800, "width"),
        () -> assertTrue(dim.getHeight() == 600, "height"));
  }
  @Test
  public void exceptions() {
    // assert exception type
    assertThrows(RuntimeException.class, () -> {
      throw new NullPointerException();
    });
    // assert on the expected exception
    Throwable exception = expectThrows(RuntimeException.class, () -> {
      throw new NullPointerException("should not be null");
    });
    assertEquals("should not be null", exception.getMessage());
  }
}
           

三、假設、标簽和禁止測試

假設、标簽和禁止測試是JUnit 4的特性,在JUnit 5中仍然得以保留。不同的是假設中也支援Lambda表達式,假設的思想是如果假設條件沒有得到滿足,那麼跳過測試執行。标簽Tags等同于JUnit 4的測試分類的概念,可以對測試類和方法進行分類。JUnit 4禁止測試使用了@Ignore注釋,而在JUnit 5中則使用@Disabled注釋。

public class Test3 {
  @Test
  @Disabled
  public void disabledTest() {    
    // ...  
  }
  @Test
  @Tag("jenkins")
  public void jenkinsOnly() {
    // ...
  }

  @Test
  public void windowsOnly() {
    Assumptions.assumeTrue(System.getenv("OS").startsWith("Windows"));
    // ...
  }
}
           

四、擴充模型

JUnit 5提供了一套新的擴充API,取代了以前的@RunWith和@Rule擴充機制。JUnit 4的測試類被限制到僅有一個Runner上,而新的擴充模型則允許一個類或方法keyii注冊到多種擴充。

@ExtendWith(MockitoExtension.class)
@ExtendWith(CdiUnitExtension.class)
public class Test4 {
  @Test
  @DisplayName("awesome test")
  void dependencyInjection(TestInfo testInfo) {
    assertEquals("awesome test", testInfo.getDisplayName());
  }
}
           

JUnit 5内建的擴充還支援方法級的依賴注入。

支援Hamcrest比對和AssertJ斷言庫

JUnit 5支援Hamcrest比對和AssertJ斷言庫,可以用它們來代替JUnit 5的方法。

public class Test5 {
  @Test
  public void emptyString() {
    // JUnit 5
    org.junit.gen5.api.Assertions.assertTrue("".isEmpty());

    // AssertJ
    org.assertj.core.api.Assertions.assertThat("").isEmpty();

    // Hamcrest
    org.hamcrest.MatcherAssert.assertThat("", isEmptyString());
  }
}
           

JUnit 5的首頁見:

https://github.com/junit-team/junit5

有興趣的朋友可以關注。