日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

简而言之:JRunner

發(fā)布時(shí)間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简而言之:JRunner 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)于JUnit測(cè)試要點(diǎn)的多篇教程的第四章介紹了該工具可交換測(cè)試運(yùn)行器體系結(jié)構(gòu)的目的,并介紹了一些可用的實(shí)現(xiàn)。 正在進(jìn)行的示例通過編寫參數(shù)化測(cè)試的不同可能性擴(kuò)大了主題。

由于我已經(jīng)發(fā)布了JUnit Rules的介紹,因此我決定跳過關(guān)于該主題的已宣布部分。 相反,我對(duì)后者進(jìn)行了較小的更新。

測(cè)試跑步者架構(gòu)

不要害怕為了偉大而放棄美好。
約翰·洛克菲勒

在先前的文章中,我們學(xué)習(xí)了將某些xUnit測(cè)試模式[MES]與JUnit一起使用。 工具運(yùn)行時(shí)的默認(rèn)行為很好地支持了這些概念。 但是有時(shí)需要針對(duì)特定??的測(cè)試類型或目標(biāo)更改或補(bǔ)充后者。

考慮例如集成測(cè)試 ,該測(cè)試通常需要在特定環(huán)境中運(yùn)行。 或想象一組包含子系統(tǒng)規(guī)范的測(cè)試用例,應(yīng)該為常見的測(cè)試執(zhí)行而組成。

為此,JUnit支持使用各種類型的測(cè)試處理器。 因此,它在運(yùn)行時(shí)將測(cè)試類實(shí)例化,測(cè)試執(zhí)行和結(jié)果報(bào)告委托給此類處理器,這些處理器必須是org.junit.Runner子類型。

測(cè)試用例可以使用@RunWith注釋指定其預(yù)期的運(yùn)行器類型。 如果未指定任何類型,那么運(yùn)行時(shí)將選擇BlockJUnit4ClassRunner作為默認(rèn)值。 負(fù)責(zé)每個(gè)測(cè)試運(yùn)行一個(gè)新的測(cè)試實(shí)例,并調(diào)用諸如隱式設(shè)置或拆卸處理程序之類的生命周期方法(另請(qǐng)參見有關(guān)測(cè)試結(jié)構(gòu)的章節(jié))。

@RunWith( FooRunner.class ) public class BarTest {

該代碼段顯示了如何將虛構(gòu)的FooRunner指定為也是虛構(gòu)的BarTest測(cè)試處理器。

通常,無需編寫自定義測(cè)試運(yùn)行程序。 但是,如果需要的話, Michael Scharhag最近就對(duì)JUnit的運(yùn)行器體系結(jié)構(gòu)進(jìn)行了很好的解釋。

看起來特殊測(cè)試運(yùn)行程序的用法很簡(jiǎn)單,所以讓我們看一下其中的幾個(gè):

套房和類別

Suite可能是最著名的處理器之一。 它允許以分層或主題結(jié)構(gòu)的方式運(yùn)行測(cè)試和/或其他套件的集合。 注意,指定類本身通常沒有主體實(shí)現(xiàn)。 它帶有一系列測(cè)試類的注釋,這些類通過運(yùn)行套件來執(zhí)行:

@RunWith(Suite.class) @SuiteClasses( { NumberRangeCounterTest.class,// list of test cases and other suites } ) public class AllUnitTests {}

但是,套件的結(jié)構(gòu)功能受到一定限制。 因此,JUnit 4.8引入了鮮為人知的Categories概念。 這樣就可以定義自定義類別類型,例如單元測(cè)試,集成測(cè)試和驗(yàn)收測(cè)試。 要將測(cè)試用例或方法分配給這些類別之一,必須提供Category注釋:

// definition of the available categories public interface Unit {} public interface Integration {} public interface Acceptance {}// category assignment of a test case @Category(Unit.class) public class NumberRangeCounterTest {[...] }// suite definition that runs tests // of the category 'Unit' only @RunWith(Categories.class) @IncludeCategory(Unit.class) @SuiteClasses( { NumberRangeCounterTest.class,// list of test cases and other suites } ) public class AllUnitTests {}

帶Categories注釋類定義了只運(yùn)行與指定類別匹配的類列表測(cè)試的套件。 通過包含和/或排除注釋來完成規(guī)范。 請(qǐng)注意,類別可以在Maven或Gradle構(gòu)建中使用,而無需定義特定的套件類(請(qǐng)參見JUnit文檔的類別部分)。

有關(guān)類別的更多信息: John Ferguson Smart撰寫了有關(guān)使用JUnit類別對(duì)測(cè)試進(jìn)行分組的詳細(xì)說明。

由于通常認(rèn)為套件類列表和類別注釋的維護(hù)有些繁瑣,因此您可能更喜歡通過測(cè)試后綴名稱àFooUnitTest而不是FooTest進(jìn)行分類。 這允許在運(yùn)行時(shí)在類型范圍上過濾類別。

但是JUnit本身不支持此過濾,因此您可能需要一個(gè)特殊的運(yùn)行器來動(dòng)態(tài)收集可用的匹配測(cè)試。 Johannes Link的ClasspathSuite是提供適當(dāng)實(shí)現(xiàn)的庫(kù)。 如果您碰巧在OSGi環(huán)境中進(jìn)行集成測(cè)試,則Rüdiger的BundleTestSuite會(huì)對(duì)捆綁BundleTestSuite執(zhí)行類似的操作。

在對(duì)如何將測(cè)試運(yùn)行程序用于測(cè)試?yán)壍牡谝挥∠笾?#xff0c;讓我們繼續(xù)本教程的示例,并進(jìn)行一些更令人興奮的事情。

參數(shù)化測(cè)試

本教程中使用的示例都是關(guān)于編寫一個(gè)簡(jiǎn)單的數(shù)字范圍計(jì)數(shù)器,該計(jì)數(shù)器從給定值開始傳遞一定數(shù)量的連續(xù)整數(shù)。 另外,計(jì)數(shù)器取決于存儲(chǔ)類型以保留其當(dāng)前狀態(tài)。 有關(guān)更多信息,請(qǐng)參閱前面的章節(jié)。

現(xiàn)在,假定應(yīng)將由構(gòu)造函數(shù)參數(shù)初始化的NumberRangeCounter作為API提供。 因此,我們可以認(rèn)為實(shí)例創(chuàng)建檢查給定參數(shù)的有效性是合理的。

我們可以指定適當(dāng)?shù)臉O端情況,并通過每個(gè)測(cè)試通過IllegalArgumentException予以確認(rèn)。 使用帶有Java 8 Lambdas方法的Clean JUnit Throwable-Tests方法,這種驗(yàn)證storage參數(shù)一定不能為null的測(cè)試可能看起來像這樣:

@Testpublic void testConstructorWithNullAsStorage() {Throwable actual = thrown( () -> new NumberRangeCounter( null, 0, 0 ) );assertTrue( actual instanceof IllegalArgumentException );assertEquals( NumberRangeCounter.ERR_PARAM_STORAGE_MISSING,actual.getMessage() );}

請(qǐng)注意,我堅(jiān)持使用JUnit內(nèi)置功能進(jìn)行驗(yàn)證。 我將在另一篇文章中介紹特定匹配器庫(kù)( Hamcrest , AssertJ )的優(yōu)缺點(diǎn)。

為了使該職位保持范圍,我還跳過了有關(guān)NPE是否比IAE更好的討論。

如果我們必須涵蓋很多這種極端情況,則上述方法可能會(huì)導(dǎo)致很多非常相似的測(cè)試。 JUnit提供了Parameterized實(shí)現(xiàn),以減少這種冗余。 這個(gè)想法是為通用測(cè)試結(jié)構(gòu)提供各種數(shù)據(jù)記錄。

為此,使用帶有@Parameters注釋的公共靜態(tài)方法來創(chuàng)建數(shù)據(jù)記錄作為對(duì)象數(shù)組的集合。 此外,測(cè)試用例需要一個(gè)帶有參數(shù)的公共構(gòu)造函數(shù),該參數(shù)與記錄提供的數(shù)據(jù)類型匹配。

參數(shù)化處理器針對(duì)由參數(shù)方法提供的每個(gè)記錄運(yùn)行給定測(cè)試。 這意味著對(duì)于每種測(cè)試和記錄組合,都會(huì)創(chuàng)建一個(gè)新的測(cè)試類實(shí)例。 構(gòu)造函數(shù)參數(shù)將存儲(chǔ)為字段,并且可以通過測(cè)試進(jìn)行訪問以進(jìn)行設(shè)置,練習(xí)和驗(yàn)證:

@RunWith( Parameterized.class ) public class NumberRangeCounterTest {private final String message;private final CounterStorage storage;private final int lowerBound;private final int range;@Parameterspublic static Collection<Object[]> data() {CounterStorage dummy = mock( CounterStorage.class );return Arrays.asList( new Object[][] { { NumberRangeCounter.ERR_PARAM_STORAGE_MISSING, null, 0, 0 }, { NumberRangeCounter.ERR_LOWER_BOUND_NEGATIVE, dummy, -1, 0 },[...] // further data goes here... } );}public NumberRangeCounterTest(String message, CounterStorage storage, int lowerBound, int range ){this.message = message;this.storage = storage;this.lowerBound = lowerBound;this.range = range;}@Testpublic void testConstructorParamValidation() {Throwable actual = thrown( () -> new NumberRangeCounter( storage, lowerBound, range ) );assertTrue( actual instanceof IllegalArgumentException );assertEquals( message, actual.getMessage() );}[...] }

盡管該示例確實(shí)減少了測(cè)試冗余,但至少在可讀性方面值得商bat。 最后,這通常取決于測(cè)試的數(shù)量和特定測(cè)試數(shù)據(jù)的結(jié)構(gòu)。 但絕對(duì)不幸的是, 不使用任何記錄值的測(cè)試也將執(zhí)行多次。

因此,參數(shù)化測(cè)試通常保存在單獨(dú)的測(cè)試用例中,通常感覺更像是一種解決方法,而不是適當(dāng)?shù)慕鉀Q方案。 因此,一個(gè)聰明的人想到了提供一種可以避免上述問題的測(cè)試處理器的想法。

JUnitParams

JUnitParams庫(kù)提供JUnitParamsRunner和@Parameter類型。 param批注指定給定測(cè)試的數(shù)據(jù)記錄。 注意使用相同簡(jiǎn)單名稱的JUnit批注的區(qū)別。 后者標(biāo)記了提供數(shù)據(jù)記錄的方法!

可以使用JUnitParams重寫上面的測(cè)試方案,如以下代碼片段所示:

@RunWith( JUnitParamsRunner.class ) public class NumberRangeCounterTest {public static Object data() {CounterStorage dummy = mock( CounterStorage.class );return $( $( ERR_PARAM_STORAGE_MISSING, null, 0, 0 ),$( ERR_LOWER_BOUND_NEGATIVE, dummy, -1, 0 ) ); }@Test@Parameters( method = "data" )public void testConstructorParamValidation(String message, CounterStorage storage, int lowerBound, int range ) {Throwable actual = thrown( () -> new NumberRangeCounter( storage, lowerBound, range ) );assertTrue( actual instanceof IllegalArgumentException );assertEquals( message, actual.getMessage() );}[...] }

雖然這當(dāng)然更緊湊并且乍一看看上去更干凈,但仍有一些構(gòu)造需要進(jìn)一步說明。 $(...)方法是在JUnitParamsRunner (靜態(tài)導(dǎo)入)中定義的,是創(chuàng)建對(duì)象數(shù)組的快捷方式。 一旦習(xí)慣了,數(shù)據(jù)定義就會(huì)變得更具可讀性。

$快捷方式用于方法data以創(chuàng)建嵌套的對(duì)象數(shù)組作為返回值。 盡管運(yùn)行程序期望在運(yùn)行時(shí)嵌套數(shù)據(jù)數(shù)組,但它能夠?qū)⒑?jiǎn)單的對(duì)象類型作為返回值來處理。

測(cè)試本身具有一個(gè)附加的@Parameters批注。 批注的方法聲明是指用于為測(cè)試提供聲明的參數(shù)的數(shù)據(jù)提供程序 。 方法名稱在運(yùn)行時(shí)通過反射解析。 這是解決方案的缺點(diǎn),因?yàn)樗诰幾g時(shí)不安全。

但是在其他用例場(chǎng)景中,您可以指定數(shù)據(jù)提供程序類或隱式值,因此不會(huì)受到這種折衷的影響。 有關(guān)更多信息,請(qǐng)參見例如該庫(kù)的快速入門指南 。

另一個(gè)巨大的優(yōu)點(diǎn)是,現(xiàn)在只有那些測(cè)試針對(duì)使用@Parameters批注的數(shù)據(jù)記錄運(yùn)行。 標(biāo)準(zhǔn)測(cè)試僅執(zhí)行一次。 反過來,這意味著可以將參數(shù)化測(cè)試保留在設(shè)備的默認(rèn)測(cè)試用例中。

包起來

以上各節(jié)概述了JUnit可交換測(cè)試運(yùn)行器體系結(jié)構(gòu)的意義和目的。 它介紹了套件和類別以顯示基本用法,并舉例說明了測(cè)試運(yùn)行程序如何簡(jiǎn)化編寫與數(shù)據(jù)記錄相關(guān)的測(cè)試的任務(wù)。

有關(guān)其他測(cè)試運(yùn)行程序的列表,junit.org上的“ 測(cè)試運(yùn)行程序”和“ 自定義運(yùn)行程序 ”頁(yè)面可能是一個(gè)不錯(cuò)的起點(diǎn)。 并且,如果您想知道標(biāo)題圖片的Theories主題是什么,可以看看Florian Waibels在JUnit上 發(fā)表的文章– Practice和@Theory之間的區(qū)別 。

下次在Nutshell中使用JUnit時(shí),我最后將介紹可用于驗(yàn)證測(cè)試結(jié)果的各種斷言。

參考文獻(xiàn)

[MES] xUnit測(cè)試模式,Gerard Meszaros,2007年

翻譯自: https://www.javacodegeeks.com/2014/09/junit-in-a-nutshell-test-runners.html

總結(jié)

以上是生活随笔為你收集整理的简而言之:JRunner的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。