摘要:是對測試樣例的建模,用來組合多個測試樣例,是中的核心內容。也是一個虛類,子類應該實現方法來決定對于是否運行。如下列代碼所示組合了和,為運行時異常和斷言錯誤屏蔽了不一致的方面,可以向上提供錯誤信息和樣例信息。
Junit的工程結構
從上圖可以清楚的看出Junit大致分為幾個版塊,接下來一一簡略介紹這些版塊的作用。
runner:定義了Junit模型中的許多基本概念,只要是一些虛類和接口,是整個Junit工程的基石
runners:提供了從注解中使用反射完成測試用例執行的實現
interval:提供了在Runner中許多虛類的默認實現,包括各類RunnerBuilder如基于注解提供Builder、各類Matchers、各類Request如類測試Request、方法測試Request。
rules:用于用戶自定義擴展,規定對于不同statement的用戶自定義行為
matchers:主要用于AssertThat方法,在4.4之后廢棄
validator:從類、方法和域多個方面檢查測試樣例
experimental:一些測試特性
Runner中的基本概念Runner:以Notifier為參數允許測試樣例,運行過程中的Notifier負責監視測試過程
Request:負責記錄測試樣例的Description信息,同事負責提供對應的Runner。可以通過Computer結合指定或默認的RunnerBuilder來直接為一系列測試類統一提供Runner
Description:描述測試樣例,使用Composite模式,組合多個樣例
Result:記錄異常和失敗,內置一個Listener來實現與測試過程的同步,測試完成時count自增,有樣例失敗則加入Failure列表
Failure:將斷言失敗和拋出異常綜合在同一個框架下,同時提供了Description的信息
Listener:監視測試過程,典型的觀察者模式
Notifier:管理一系列Listener,保證線程安全
Filter:指定條件,只運行符合條件的測試樣例,可以動態添加,為每次測試增加了靈活性
Runner中的依賴關系JunitCore負責提供給用戶統一的交互,從命令行運行測試樣例。Notifier是一個虛類,子類需要實現如何通知Listener的方法,負責管理Listener集合,內部內置了一個靜態的SafeNotifier,該類提供了一個run方法,來簡單依次通知所有Listener,它用來實現在測試開始和失敗出現的時候通知所有Listener。
Description是對測試樣例的建模,用來組合多個測試樣例,是Runner中的核心內容。
Filter也是一個虛類,子類應該實現shouldRun方法來決定對于Description是否運行。同時依然實現一個靜態方法來提供什么都不過濾,以及一個判斷原子描述是否等于期望描述的過濾器,對于非原子描述若其子描述均不等于期望描述則濾掉。如下列代碼所示:
/** * Returns a {@code Filter} that only runs the single method described by * {@code desiredDescription} */ public static Filter matchMethodDescription(final Description desiredDescription) { return new Filter() { @Override public boolean shouldRun(Description description) { if (description.isTest()) { return desiredDescription.equals(description); } // explicitly check if any children want to run for (Description each : description.getChildren()) { if (shouldRun(each)) { return true; } } return false; } @Override public String describe() { return String.format("Method %s", desiredDescription.getDisplayName()); } }; }
Failure組合了Description和Throwable,為運行時異常和斷言錯誤屏蔽了不一致的方面,可以向上提供錯誤信息和樣例信息。
Request負責提供具體的Runner來run對應的測試樣例,同時是Filter作用的主體,對于Filter,會返回一個新的FilterRequest,代碼如下:
package org.junit.internal.requests;
import org.junit.internal.runners.ErrorReportingRunner;
import org.junit.runner.Request;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
/**
* A filtered {@link Request}.
*/
public final class FilterRequest extends Request {
private final Request request;
/*
* We have to use the f prefix, because IntelliJ"s JUnit4IdeaTestRunner uses
* reflection to access this field. See
* https://github.com/junit-team/junit/issues/960
*/
private final Filter fFilter;
/**
* Creates a filtered Request
*
* @param request a {@link Request} describing your Tests
* @param filter {@link Filter} to apply to the Tests described in
* request
*/
public FilterRequest(Request request, Filter filter) {
this.request = request;
this.fFilter = filter;
}
@Override
public Runner getRunner() {
try {
Runner runner = request.getRunner();
fFilter.apply(runner);
return runner;
} catch (NoTestsRemainException e) {
return new ErrorReportingRunner(Filter.class, new Exception(String
.format("No tests found matching %s from %s", fFilter
.describe(), request.toString())));
}
}
}
Runner中的JunitCore
JUnitCore使用外觀模式(facade),對外提供一致的界面,同時支持運行JUnit 4或JUnit 3.8.x用例,通過命令行執行用例.首先它使用jUnitCommandLineParseResult解析外部參數,將默認的TextListener加入內置的Notifier。它所運行的Runner也是由jUnitCommandLineParseResult提供的,先行通過測試filter掉不需要的樣例,最后調用Runner的run方法。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65435.html
摘要:前言在這次的博客中我們將著重于的許多集成性功能來討論中的種種設計模式。裝飾器模式裝飾器模式是為了在原有功能上加入新功能,在中絕對屬于使用最頻繁架構中最核心的模式,等都是通過裝飾器模式來完成擴展的。 前言 在這次的博客中我們將著重于Junit的許多集成性功能來討論Junit中的種種設計模式。可以說Junit的實現本身就是GOF設計原則的范例教本,下面就讓我們開始吧。 裝飾器模式 裝飾器...
摘要:前言在建立的過程中,往往需要對當前的測試樣例和注解進行驗證,比如檢查測試類是否含有非靜態內部類,測試類是否是的。的驗證機制非常精致而優美,在本次博客中我們就主要來談一談機制的實現。首先在中定義三個默認的類,如下。 前言 在建立Runner的過程中,往往需要對當前的測試樣例和注解進行驗證,比如檢查測試類是否含有非靜態內部類,測試類是否是Public的。Junit的驗證機制非常精致而優美...
摘要:的作用是包裝從生成的邏輯,提供兩種方案生成和。最后從生成也異常簡單,也就是實現其方法返回該。 前言 盡管在第二次博客中我們講述了Runner的運行機制,但是許多其他特性比如Filter是如何與運行流程結合卻并不清楚。這次我們來回顧整理一下Junit的執行流程,給出各種特性生效的機理,并分析一些代碼中精妙的地方。 Junit的執行流程 JUnitCore的RunMain方法,使用jUn...
摘要:前言上次的博客中我們著重介紹了的機制,這次我們將聚焦到自定義擴展上來。在很多情形下我們需要在測試過程中加入一些自定義的動作,這些就需要對進行包裝,為此提供了以接口和為基礎的擴展機制。 前言 上次的博客中我們著重介紹了Junit的Validator機制,這次我們將聚焦到自定義擴展Rule上來。在很多情形下我們需要在測試過程中加入一些自定義的動作,這些就需要對statement進行包裝,...
摘要:前言在上次的博客中我們提到了最終由以為參數執行測試樣例,但并沒有解釋到底測試方法是如何被運行起來的,一些諸如之類的特性又到底是如何實現的呢。這次我們就集中深入的運行機制來探究樣例是如何被運行的。使用拿到的直接運行方法。 前言 在上次的博客中我們提到了最終由Runner以Notifier為參數執行測試樣例,但并沒有解釋到底測試方法是如何被運行起來的,一些諸如RunWith、RunAft...
閱讀 3155·2021-11-22 12:01
閱讀 3775·2021-08-30 09:46
閱讀 789·2019-08-30 13:48
閱讀 3220·2019-08-29 16:43
閱讀 1667·2019-08-29 16:33
閱讀 1855·2019-08-29 13:44
閱讀 1420·2019-08-26 13:45
閱讀 2237·2019-08-26 11:44