JUnit是流行的Java單元測試框架,近日JUnit Lambda團隊宣布發布新的主要版本——JUnit 5 alpha版本。通過一個成功的眾籌活動允許全職開發人員工作在該項目上,JUnit 5的主要變化集中在去除了JUnit 4帶給開發人員的普遍問題,同時修改了框架以便于將來的變更。與構建工具和集成開發環境的整合仍需要一些額外的工作。
JUnit 5已經適應了開發人員每天編寫單元測試的方式,開發人員對此非常感激。例如,盡管JUnit FAQ傳統上反對在一個單元測試中放多個斷言,但是一些軼事證據表明,開發人員傾向于這么做。一個測試中包括多個斷言的風險是一旦其中一個失敗,測試執行就會停止,不會執行其他的斷言。因此,JUnit 5 支持分組斷言(grouped assertions),所有的斷言都會被執行,即使其中一個或多個斷言失?。?/p>
@Test
void groupedAssertions() {
assertAll("address",
() -> assertEquals("John", address.getFirstName()),
() -> assertEquals("User", address.getLastName())
);
}
來自JUnit 5用戶指南的示例代碼。
讓人不滿意的另一個常見原因是對測試異常的支持,因為JUnit 4中提供的幾種方式都不能滿足開發人員的需求。人們可以用@Test注解中的”expected“選項表示期望拋出的異常類型;但是,對于更復雜的斷言,這是不夠靈活的,比如在拋出的異常中檢查異常信息。在這種情況下,開發人員可以用@Rule 和 ExpectedException,這確實支持使用匹配器來檢查異常信息;然而,即使是ExpectedException 也不足以進一步測試像自定義字段或方法的異常對象,或在拋出異常的方法后執行額外的斷言。
為了解決這個問題,JUnit 5提供了一個新的斷言,expectthrows,不僅可以檢查一個特定方法拋出的預期異常,同時將異常對象作為一個結果返回,允許進一步測試。
@Test
void exceptionTesting() {
Throwable exception = expectThrows(IllegalArgumentException.class,
() -> { throw new IllegalArgumentException("a message"); }
);
assertEquals("a message", exception.getMessage());
}
來自JUnit 5用戶指南的示例代碼。
擴展性也是新版本關注的一個方面。JUnit 4主要的擴展機制是@RunWith。但是,@RunWith在任何給定的測試類上只能使用一次,這意味著開發人員不能同時使用,例如,Parameterized 在同樣的測試中應用不同的數據以及MockitoJUnitRunner自動設置mocks。在JUnit 5 @RunWith已經被@ExtendWith取代,這是一個新的擴展機制,支持多個實例被使用。
為了讓開發人員逐步升級到新版本,JUnit 5所有的類已經遷移到新的包,許多注解已經重命名。此外,JUnit Lambda團隊為JUnit 4創建了一個JUnit 5 Runner ,允許使用JUnit 5所有特性的同時仍然以JUnit 4為主要的測試框架。這使得JUnit 4和JUnit 5有可能在同一個項目中同時使用,使過渡變得更容易。
被關注的問題還有,通過語義化的版本號命名(semantic versioning)和加注解的API,使得未來的變更更加方便,甚至包括那些向后不兼容的變更。從JUnit 5開始,測試框架中每一個公共類和接口都將標有下列值之一:
Internal:不適合在框架之外使用,隨時可能被刪除,并且可能不會事先通知。
Deprecated:不應使用的,在下一個小版本可能會去掉。
Experimental:用來收集對新概念的反饋,它可能被改進,也可能在沒有事先通知的情況下被刪除。
Maintained:從當前版本到至少下一個小版本沒有向后不兼容的更改,如果計劃刪除,它首先會被修改為Deprecated。
Stable:在目前的主要版本沒有向后不兼容的更改。
在上一個主要版本發布十年之后,JUnit似乎趕上了時代的步伐。雖然與構建工具和集成開發環境的整合還需要一些工作,但是為Maven和Gradle 提供的插件看起來是相當先進的,這似乎表明,在可預見的未來JUnit將繼續是主要的Java測試框架。
原文轉自:http://www.infoq.com/cn/news/2016/03/junit5-alpha