junit测试起名字规则_如何在JUnit 5中替换规则
junit測試起名字規則
最近發布的JUnit 5(又名JUnit Lambda) alpha發行版引起了我的興趣,在瀏覽文檔時,我注意到規則以及運行程序和類規則都消失了。 根據文檔,這些部分競爭的概念已被單個一致的擴展模型取代。
多年來, Frank和我寫了一些規則來幫助執行重復性任務,例如測試SWT UI , 忽略某些環境中的測試 , 注冊(測試)OSGi服務 , 在單獨的線程中運行測試等等。
因此,我對將現有規則轉換為新概念以使它們可以在JUnit 5上本地運行特別感興趣,為了探索擴展的功能,我選擇了兩個特性完全不同的規則,并嘗試將其遷移到JUnit 5 。
這些實驗的重點是查看規則和擴展之間的概念已發生了變化。 因此,我選擇重寫JUnit 4意味著不考慮向后兼容性。
如果您有興趣從JUnit 4遷移到5或探索在JUnit 5中運行現有規則的可能性,則可能需要參加各自的討論。
第一個候選對象是ConditionalIgnoreRule ,它與@ConditionalIgnore批注一起使用。 該規則評估需要用注釋指定的條件,并據此確定是否執行測試。
另一個候選者是內置的TemporaryFolder規則 。 顧名思義,它允許創建在測試完成時刪除的文件和文件夾。
因此,它在測試執行之前和之后掛接,以創建一個根目錄以在其中存儲文件和文件夾并清理該目錄。 另外,它提供了實用程序方法來在根目錄中創建文件和文件夾。
擴展說明
在詳細介紹向擴展的遷移規則之前,讓我們簡要了解一下新概念。
測試執行遵循一定的生命周期。 可以延長生命周期的每個階段都由一個接口表示。 擴展可以實現某些階段的興趣,因為它們實現了相應的接口。
使用ExtendWith批注,測試方法或類可以表示它在運行時需要特定的擴展。 所有擴展都有一個公共的超級接口: ExtensionPoint 。 ExtensionPoint的類型層次結構列出了擴展當前可以掛接到的所有位置。
例如,下面的代碼應用了一個虛構的MockitoExtension來注入模擬對象:
@ExtendWith(MockitoExtension.class) class MockTest {@MockFoo fooMock; // initialized by extension with mock( Foo.class ) }MockitoExtension將提供一個默認的構造函數,以便它可以在運行時實例化并實現必要的擴展接口,以便能夠將@Mock注入到所有@Mock注釋的字段中。
條件忽略
規則的重復模式是提供帶有注釋的串聯服務,該注釋用于標記和/或配置希望使用該服務的測試方法。 在這里,ConditionalIgnoreRule檢查其運行的所有測試方法,并尋找ConditinalIgnore批注。 如果找到這樣的注釋,則評估其條件,如果滿足,則忽略測試。
這是ConditionalIgnoreRule實際運行的樣子:
@Rule public ConditionalIgnoreRule rule = new ConditionalIgnoreRule();@Test @ConditionalIgnore( condition = IsWindowsPlatform.class ) public void testSomethingPlatformSpecific() {// ... }現在,讓我們看一下代碼在JUnit 5中的外觀:
@Test @DisabledWhen( IsWindowsPlatform.class ) void testSomethingPlatformSpecific() {// ... }首先,您會注意到注釋已更改其名稱。 為了匹配使用術語Disabled而不是忽略的JUnit 5約定,該擴展還將其名稱更改為DisabledWhen 。
盡管DisabledWhen注釋是由DisabledWhenExtension驅動的,但是沒有任何東西表明需要擴展。 其原因被稱為元注釋,并且在查看DisabledWhen的聲明方式時可以最好地說明它們:
@Retention(RetentionPolicy.RUNTIME) @ExtendWith(DisabledWhenExtension.class) public @interface DisabledWhen {Class<? extends DisabledWhenCondition> value(); }注釋(元)帶有處理它的擴展名注釋。 在運行時,JUnit 5測試執行器負責其余的工作。 如果遇到帶注釋的測試方法,并且該注釋又由ExtendWith元注釋,則實例化各個擴展并將其包含在生命周期中。
真的很整潔嗎? 在不指定相應規則的情況下注釋測試方法時,此技巧還可以避免疏忽。
在幕后, DisabledWhenExtension實現了TestExexutionCondition接口。 對于每個測試方法,都將調用其唯一的evaluate()方法,并且必須返回一個ConditionEvaluationResult ,該ConditionEvaluationResult確定是否應該執行測試。
其余代碼與以前基本相同。 查找并找到DisabledWhen注釋時,將創建指定條件類的實例,并詢問是否應執行測試。 如果執行被拒絕,則返回一個禁用的ConditionEvaluationResult ,并且框架將相應地執行操作。
臨時文件夾
在將TemporaryFolder規則轉換為異常之前,讓我們看一下該規則的組成。 首先,該規則將在測試設置和拆卸期間進行設置并清理一個臨時文件夾。 但是,它還為測試提供了訪問在該根文件夾內創建(臨時)文件和文件夾的方法的權限。
遷移到擴展后,不同的職責變得更加明顯。 以下示例顯示了如何使用它:
@ExtendWith(TemporaryFolderExtension.class) class InputOutputTestprivate TemporaryFolder tempFolder;@Testvoid testThatUsesTemporaryFolder() {F?ile f?ile = tempFolder.newF?ile();// ...} }TemporaryFolderExtension掛接到測試執行生命周期中,以提供和清除臨時文件夾,并為所有TemporaryFolder字段提供此類實例。 而TemporaryFolder允許訪問在根文件夾中創建文件和文件夾的方法。
為了注入TemporaryFolder ,該擴展實現了InstancePostProcessor接口。 創建測試實例后立即調用其postProcessTestInstance方法。 在該方法中,它可以通過TestExtensionContext參數訪問測試實例,并且可以將TemporaryFolder注入所有匹配的字段中。
對于一個類聲明多個TemporaryFolder字段的極少數情況,每個字段都被分配一個新實例,并且每個實例都有其自己的根文件夾。
在此過程中創建的所有注入的TemporaryFolder實例都保存在一個集合中,以便稍后進行清理時可以對其進行訪問。
要在執行測試后進行清理,需要實現另一個擴展接口: AfterEachExtensionPoint 。 每次測試完成后,將調用其唯一的afterEach方法。 并且此處的TemporaryFolderExtension實現清除了所有已知的TemporaryFolder實例。
現在我們可以與TemporaryFolder規則的功能相提并論,現在還可以支持新功能:方法級依賴注入。
在JUnit 5中,現在允許方法具有參數。
這意味著我們的擴展程序不僅應該能夠注入字段,而且還應該能夠注入TemporaryFolder類型的方法參數。 希望創建臨時文件的測試可以請求注入TemporaryFolder如以下示例所示:
通過實現MethodParameterResolver接口,擴展可以參與解析方法參數。 對于測試方法的每個參數,都會調用擴展的supports()方法來確定它是否可以為給定參數提供值。 對于TemporaryFolderExtension ,實現將檢查參數類型是否為TemporaryFolder并在這種情況下返回true 。 如果需要更廣泛的上下文,則當前方法調用上下文和擴展上下文還提供了supports()方法。
現在,該擴展程序決定支持某個參數,它的resolve()方法必須提供一個匹配的實例。 同樣,提供了周圍的環境。 TemporaryFolderExtension僅返回一個唯一的TemporaryFolder實例,該實例知道(臨時)根文件夾并提供在其中創建文件和子文件夾的方法。
但是請注意,聲明無法解析的參數被視為錯誤。 因此,如果遇到沒有匹配解析器的參數,則會引發異常。
在擴展中存儲狀態
您可能已經注意到, TemporaryFolderExtension保持其狀態(即,它已創建的臨時文件夾的列表),當前是一個簡單字段。 盡管測試表明這確實可行,但是文檔中沒有地方指出在調用不同擴展名時都使用同一實例。 因此,如果JUnit 5此時更改其行為,則在這些調用期間狀態可能會丟失。
好消息是,JUnit 5提供了一種維護稱為Store的擴展狀態的方法。 正如文檔所述,它們為擴展提供了保存和檢索數據的方法 。
該API與簡化Map的API類似,并且允許存儲鍵值對,獲取與給定鍵關聯的值以及刪除給定鍵。 鍵和值都可以是任意對象。 可以通過將TestExtensionContext作為參數傳遞給每個擴展方法(例如beforeEach , afterEach )來到達存儲。每個TestExtensionContext實例都封裝了正在執行當前測試的上下文 。
例如,在beforeEach ,值將存儲在擴展上下文中,如下所示:
@Override public void beforeEach( TestExtensionContext context ) {context.getStore().put( KEY, ... ); }以后可以像這樣檢索:
@Override public void afterEach( TestExtensionContext context ) {Store store = context.getStore();Object value = store.get( KEY );// use value... }為了避免可能發生的名稱沖突,可以為某些命名空間創建存儲。 上面使用的context.getStore()方法獲取默認名稱空間的存儲。 要獲取特定命名空間的商店,請使用
context.getStore( Namespace.of( MY, NAME, SPACE );名稱空間是通過對象數組{ MY, NAME, SPACE }在此示例中。
返還TemporaryFolderExtension以使用Store的練習留給讀者。
運行代碼
- 可以在以下GitHub存儲庫中找到此處討論的兩個擴展的擴展實現: https : //github.com/rherrmann/junit5-experiments
該項目設置為在安裝了Maven支持的Eclipse中使用。 但是在具有Maven支持的其他IDE中編譯和運行代碼并不難。
很自然,在這種早期狀態下,尚不支持直接在Eclipse中運行JUnit 5測試。 因此,要運行所有測試,您可能需要使用“使用ConsoleRunner運行所有測試”啟動配置。 如果遇到麻煩,請參考我以前關于JUnit 5的文章中的“ 使用JUnit 5運行測試”部分,以獲得更多提示或發表評論。
總結如何在JUnit 5中替換規則
在這個小小的實驗過程中,我給人的印象是,擴展是JUnit 4中規則和朋友的不錯且完全的替代品。最后,使用新方法很有趣,并且比現有功能更簡潔。
如果您發現用擴展尚無法完成的用例,我相信如果讓他們知道 JUnit 5團隊將不勝感激。
但是請注意,截至撰寫本文時,擴展程序仍在進行中 。 該API被標記為實驗性的,如有更改,恕不另行通知。 因此,現在實際遷移JUnit 4幫助程序可能還為時過早-除非您不介意將代碼調整為可能更改的API。
如果JUnit 5擴展引起了您的興趣,您可能還需要繼續閱讀文檔的相應章節 。
翻譯自: https://www.javacodegeeks.com/2016/04/replace-rules-junit-5.html
junit測試起名字規則
總結
以上是生活随笔為你收集整理的junit测试起名字规则_如何在JUnit 5中替换规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏电脑配置推荐?
- 下一篇: 扩展 junit 框架_JUnit 5