在某次關(guān)于自主可控的技術(shù)交流中如绸,當(dāng)討論了國產(chǎn)CPU和操作系統(tǒng)的發(fā)展近況時(shí)完域,來自某個(gè)國內(nèi)主要的國產(chǎn)CPU設(shè)計(jì)單位的專家講到软吐,他們?cè)O(shè)計(jì)的國產(chǎn)CPU目前已經(jīng)在超級(jí)計(jì)算機(jī)上得到了較大規(guī)模的應(yīng)用,并且已經(jīng)能夠兼容諸多的Linux操作系統(tǒng)吟税。但是對(duì)于發(fā)展“通用型”CPU的目標(biāo)來說关噪,最主要的瓶頸還是在于“生態(tài)圈”的建設(shè)。從最基礎(chǔ)的C/C++編譯器乌妙,到JAVA虛擬機(jī)、數(shù)據(jù)庫等配套基礎(chǔ)軟件的支持的匱乏建钥,極大地限制了國產(chǎn)CPU在各個(gè)金融等各個(gè)領(lǐng)域的業(yè)務(wù)拓展藤韵。為此,他們也開始組建所謂的自主可控聯(lián)盟熊经,聯(lián)合了操作系統(tǒng)泽艘、數(shù)據(jù)庫等廠商欲险,為行業(yè)客戶提供一張?zhí)椎淖灾骺煽靥娲桨浮?br>
這個(gè)故事讓筆者想起了一則廣告詞,“大家好匹涮,才是真的好”天试。做一個(gè)項(xiàng)目,實(shí)現(xiàn)一個(gè)目標(biāo)然低,往往不是個(gè)人或者自己做好了就夠了喜每,需要前后左右各個(gè)方面的協(xié)同。中間有一環(huán)掉鏈子了雳攘,或者支持力度不夠了带兜,可能就會(huì)影響整個(gè)事情的交付結(jié)果。
對(duì)于自動(dòng)化測(cè)試來說吨灭,Junit5的推出已經(jīng)有好幾年了刚照。那么目前整個(gè)測(cè)試生態(tài)圈對(duì)Junit5的支持如何呢? 有什么在制約或者妨礙用戶從Junit4升級(jí)甚至從別的自動(dòng)化測(cè)試框架遷移到Junit5呢喧兄?
由此无畔,筆者將在本文中Junit5推出之后,整個(gè)測(cè)試生態(tài)圈的支持情況做一個(gè)盤點(diǎn)吠冤。
首先浑彰,Junit5 不再是一個(gè)單一的jar包,而是由三部分組成咨演。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
其中
JUnit平臺(tái)闸昨,其主要作用是在JVM上啟動(dòng)測(cè)試框架。它定義了一個(gè)抽象的TestEngineAPI來定義運(yùn)行在平臺(tái)上的測(cè)試框架薄风,同時(shí)還支持通過命令行饵较、Gradle和Maven來運(yùn)行平臺(tái)。
JUnit Jupiter遭赂,包含了JUnit5最新的編程模型和擴(kuò)展機(jī)制循诉。
JUnit Vintage,允許在平臺(tái)上運(yùn)行JUnit3和JUnit4的測(cè)試用例撇他。
JUnit5對(duì)Java運(yùn)行環(huán)境的最低要求是Java8,同時(shí)也兼容測(cè)試舊版本JDK編譯出來的代碼茄猫。
構(gòu)建工具的支持
我們首先來看下構(gòu)建工具的支持情況。
Maven - 姍姍來遲的官方支持
JUnit5在2017年9月10日(教師節(jié))正式發(fā)布了其5.0.0GA版本困肩。
通過這篇文章,我們可以了解到划纽,直到2018年10月24日Maven 3.6.0發(fā)布,Maven才正式原生支持Junit5锌畸。在這個(gè)版本中勇劣,Maven團(tuán)隊(duì)一并發(fā)布了 Maven Surefire Plugin 2.22.0 和Maven Failsafe plugin 2.22.0,進(jìn)而解決了對(duì)Junit5的支持問題。
在此之前比默,為了能在Maven中運(yùn)行Junit5的測(cè)試用例幻捏,需要為 Maven Surefire plugin額外提供一個(gè)Junit5團(tuán)隊(duì)提供的Junit Provider。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</plugin>
如果將Maven升級(jí)到3.6.0及以上版本命咐,那么unit-jupiter-engine這個(gè)依賴就不需要了篡九。而這中間差了有快一年的時(shí)間〈椎欤考慮到其實(shí)早在2016年Junit5就已經(jīng)發(fā)布了5.0 M1這樣一個(gè)可用版本榛臼,并提供了上述workaround,Maven對(duì)于Junit5的支持其實(shí)要落后了整整2年。
當(dāng)然這樣的支持也不是一番風(fēng)順的钝域。在Junit5的缺陷清單上讽坏,出現(xiàn)過1579號(hào)缺陷,并被認(rèn)為是maven-surefire#193所導(dǎo)致的例证。
Gradle-類似的故事
翻看了Gradle的發(fā)布?xì)v史后路呜,發(fā)現(xiàn)Gradle團(tuán)隊(duì)在4.6版本的Release Notes中興奮地宣布了對(duì)Junit5的支持。
這個(gè)時(shí)間织咧,大概比Maven團(tuán)隊(duì)早了有半年胀葱,支持力度略微好一點(diǎn)。從Gradle團(tuán)隊(duì)熱情洋溢的介紹和致謝詞中我們也能感受到笙蒙,為了能讓Gradle盡早原生支持Junit5, 后者的團(tuán)隊(duì)?wèi)?yīng)該是付出了很多的努力的抵屿。
IDE 編碼工具的支持--巴鐵一般的友誼
再來看一下IDE的支持情況。相對(duì)于構(gòu)建工具來說捅位,IDE的支持要更為提前一些轧葛,甚至都做到了同步發(fā)布。
IntelliJ IDEA
IntelliJ IDEA 在其2016.2
版本中提供了對(duì)Junit 5的支持艇搀,時(shí)間是在2006年的7月份尿扯,幾乎是和Junit5 M1版本同一時(shí)間。當(dāng)然作為第一個(gè)版本焰雕,也是有不少問題的衷笋。因此緊跟著Junit5 GA 的發(fā)布,在2017年11其2017.3版本中專門進(jìn)行了優(yōu)化矩屁,還提供了Junit4向Junit5用例的一鍵遷移功能辟宗。
Eclipse
Eclipse 在 Oxygen.1a (4.7.1a), 也幾乎是在Junit5 GA 的同時(shí)進(jìn)行發(fā)布,在其官方的發(fā)布說明中,Junit5甚至還排在對(duì)Java9支持的前面吝秕。
<iframe width="560" height="315" src="https://www.youtube.com/embed/wI3VC1lhbK8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
其余好友
Spring
對(duì)于Spring家族來說泊脐,之前是通過@RunWith的注解來執(zhí)行Junit用例的。在Junit5中烁峭,不再支持@RunWith的注解了晨抡,因此為了能將用例遷移到Junit5,Spring團(tuán)隊(duì)利用了@ExtendWith的注解。
遷移前的用例是這樣的:
@RunWith(SpringJUnit4ClassRunner.class)
public class GreetingsSpringTest {
// ...
}
遷移到Junit5的用例是這樣的
@ExtendWith(SpringExtension.class)
public class GreetingsSpringTest {
// ...
}
其中的SpringExtension類是由Spring5中的 Spring TestContext Framework所提供的耘柱。具體的需求可以參見 https://jira.spring.io/browse/SPR-13575。而Spring5 GA的時(shí)間則在2017年9月28日棍现,在Junit5 GA的同月调煎,也基本上是同步了。
SpringBoot
在SpringBoot中己肮,這一切就更簡(jiǎn)單了士袄。
@SpringBootTest
public class GreetingsSpringBootTest {
// ...
}
還是原來的味道,只是需要在pom.xml中修改下配方谎僻。
<!-- exclude junit 4 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
這里有一個(gè)大家默認(rèn)不說破的事實(shí)娄柳,時(shí)至今日spring-boot-starter-test的默認(rèn)Junit框架版本還是Junit4。
Mockito
再來看一下Mock工具對(duì)Junit5的支持情況艘绍。以Mockito為例赤拒,在Junit5推出的初期,Junit團(tuán)隊(duì)甚至利用JUnitExtension機(jī)制诱鞠,同樣地為Mockito提供了擴(kuò)展的樣例挎挖,可以讓Junit5用戶擁有基本的Mockito功能。
https://github.com/junit-team/junit5-samples/blob/r5.0.0/junit5-mockito-extension/src/main/java/com/example/mockito/MockitoExtension.java
與此同時(shí)航夺,就在Mockito2發(fā)布的前夕(和Junit5 M1差不多前后)蕉朵,收到了關(guān)于對(duì)JUnit5支持的需求。
Introduce MockitoExtension for JUnit Jupiter (a.k.a. JUnit 5) #445
https://github.com/mockito/mockito/issues/445
根據(jù)Github上各方的留言來看阳掐,這個(gè)需求直到2018年3月份才在Mockito 3.0和2.x發(fā)布始衅。隨著Junit5自身的GA和特性的增加,Mockito團(tuán)隊(duì)也在不斷地為MockitoExtension增加新的功能缭保。
簡(jiǎn)單總結(jié)下
我們以2個(gè)IDE汛闸、2個(gè)構(gòu)建工具以及1個(gè)Mock工具為例,通過回顧這5個(gè)和Junit這個(gè)測(cè)試框架最為密切的工具支持Junit5的心路歷程涮俄,我們可以總結(jié)出以下幾點(diǎn)
1)GA只是開始蛉拙。
2)提早發(fā)布M版本(預(yù)覽版)供上下游配套開發(fā),爭(zhēng)取時(shí)間彻亲,能同步發(fā)布孕锄。
3)在配套方尚未就緒之前,最好能提供臨時(shí)解決方案苞尝,如JUnit團(tuán)隊(duì)為Maven/Gradle提供了插件畸肆,為Mockito則提供了擴(kuò)展的樣例。
4)最直接的辦法宙址,是出人出代碼轴脐,幫助配套方盡快完成開發(fā)測(cè)試。
(參見Gradle團(tuán)隊(duì)那封熱情洋溢的release notes)