摘要:是對(duì)測(cè)試樣例的建模,用來(lái)組合多個(gè)測(cè)試樣例,是中的核心內(nèi)容。也是一個(gè)虛類,子類應(yīng)該實(shí)現(xiàn)方法來(lái)決定對(duì)于是否運(yùn)行。如下列代碼所示組合了和,為運(yùn)行時(shí)異常和斷言錯(cuò)誤屏蔽了不一致的方面,可以向上提供錯(cuò)誤信息和樣例信息。
Junit的工程結(jié)構(gòu)
從上圖可以清楚的看出Junit大致分為幾個(gè)版塊,接下來(lái)一一簡(jiǎn)略介紹這些版塊的作用。
runner:定義了Junit模型中的許多基本概念,只要是一些虛類和接口,是整個(gè)Junit工程的基石
runners:提供了從注解中使用反射完成測(cè)試用例執(zhí)行的實(shí)現(xiàn)
interval:提供了在Runner中許多虛類的默認(rèn)實(shí)現(xiàn),包括各類RunnerBuilder如基于注解提供Builder、各類Matchers、各類Request如類測(cè)試Request、方法測(cè)試Request。
rules:用于用戶自定義擴(kuò)展,規(guī)定對(duì)于不同statement的用戶自定義行為
matchers:主要用于AssertThat方法,在4.4之后廢棄
validator:從類、方法和域多個(gè)方面檢查測(cè)試樣例
experimental:一些測(cè)試特性
Runner中的基本概念Runner:以Notifier為參數(shù)允許測(cè)試樣例,運(yùn)行過(guò)程中的Notifier負(fù)責(zé)監(jiān)視測(cè)試過(guò)程
Request:負(fù)責(zé)記錄測(cè)試樣例的Description信息,同事負(fù)責(zé)提供對(duì)應(yīng)的Runner。可以通過(guò)Computer結(jié)合指定或默認(rèn)的RunnerBuilder來(lái)直接為一系列測(cè)試類統(tǒng)一提供Runner
Description:描述測(cè)試樣例,使用Composite模式,組合多個(gè)樣例
Result:記錄異常和失敗,內(nèi)置一個(gè)Listener來(lái)實(shí)現(xiàn)與測(cè)試過(guò)程的同步,測(cè)試完成時(shí)count自增,有樣例失敗則加入Failure列表
Failure:將斷言失敗和拋出異常綜合在同一個(gè)框架下,同時(shí)提供了Description的信息
Listener:監(jiān)視測(cè)試過(guò)程,典型的觀察者模式
Notifier:管理一系列Listener,保證線程安全
Filter:指定條件,只運(yùn)行符合條件的測(cè)試樣例,可以動(dòng)態(tài)添加,為每次測(cè)試增加了靈活性
Runner中的依賴關(guān)系JunitCore負(fù)責(zé)提供給用戶統(tǒng)一的交互,從命令行運(yùn)行測(cè)試樣例。Notifier是一個(gè)虛類,子類需要實(shí)現(xiàn)如何通知Listener的方法,負(fù)責(zé)管理Listener集合,內(nèi)部?jī)?nèi)置了一個(gè)靜態(tài)的SafeNotifier,該類提供了一個(gè)run方法,來(lái)簡(jiǎn)單依次通知所有Listener,它用來(lái)實(shí)現(xiàn)在測(cè)試開(kāi)始和失敗出現(xiàn)的時(shí)候通知所有Listener。
Description是對(duì)測(cè)試樣例的建模,用來(lái)組合多個(gè)測(cè)試樣例,是Runner中的核心內(nèi)容。
Filter也是一個(gè)虛類,子類應(yīng)該實(shí)現(xiàn)shouldRun方法來(lái)決定對(duì)于Description是否運(yùn)行。同時(shí)依然實(shí)現(xiàn)一個(gè)靜態(tài)方法來(lái)提供什么都不過(guò)濾,以及一個(gè)判斷原子描述是否等于期望描述的過(guò)濾器,對(duì)于非原子描述若其子描述均不等于期望描述則濾掉。如下列代碼所示:
/** * 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,為運(yùn)行時(shí)異常和斷言錯(cuò)誤屏蔽了不一致的方面,可以向上提供錯(cuò)誤信息和樣例信息。
Request負(fù)責(zé)提供具體的Runner來(lái)run對(duì)應(yīng)的測(cè)試樣例,同時(shí)是Filter作用的主體,對(duì)于Filter,會(huì)返回一個(gè)新的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),對(duì)外提供一致的界面,同時(shí)支持運(yùn)行JUnit 4或JUnit 3.8.x用例,通過(guò)命令行執(zhí)行用例.首先它使用jUnitCommandLineParseResult解析外部參數(shù),將默認(rèn)的TextListener加入內(nèi)置的Notifier。它所運(yùn)行的Runner也是由jUnitCommandLineParseResult提供的,先行通過(guò)測(cè)試filter掉不需要的樣例,最后調(diào)用Runner的run方法。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/65435.html
摘要:前言在這次的博客中我們將著重于的許多集成性功能來(lái)討論中的種種設(shè)計(jì)模式。裝飾器模式裝飾器模式是為了在原有功能上加入新功能,在中絕對(duì)屬于使用最頻繁架構(gòu)中最核心的模式,等都是通過(guò)裝飾器模式來(lái)完成擴(kuò)展的。 前言 在這次的博客中我們將著重于Junit的許多集成性功能來(lái)討論Junit中的種種設(shè)計(jì)模式。可以說(shuō)Junit的實(shí)現(xiàn)本身就是GOF設(shè)計(jì)原則的范例教本,下面就讓我們開(kāi)始吧。 裝飾器模式 裝飾器...
摘要:前言在建立的過(guò)程中,往往需要對(duì)當(dāng)前的測(cè)試樣例和注解進(jìn)行驗(yàn)證,比如檢查測(cè)試類是否含有非靜態(tài)內(nèi)部類,測(cè)試類是否是的。的驗(yàn)證機(jī)制非常精致而優(yōu)美,在本次博客中我們就主要來(lái)談一談機(jī)制的實(shí)現(xiàn)。首先在中定義三個(gè)默認(rèn)的類,如下。 前言 在建立Runner的過(guò)程中,往往需要對(duì)當(dāng)前的測(cè)試樣例和注解進(jìn)行驗(yàn)證,比如檢查測(cè)試類是否含有非靜態(tài)內(nèi)部類,測(cè)試類是否是Public的。Junit的驗(yàn)證機(jī)制非常精致而優(yōu)美...
摘要:的作用是包裝從生成的邏輯,提供兩種方案生成和。最后從生成也異常簡(jiǎn)單,也就是實(shí)現(xiàn)其方法返回該。 前言 盡管在第二次博客中我們講述了Runner的運(yùn)行機(jī)制,但是許多其他特性比如Filter是如何與運(yùn)行流程結(jié)合卻并不清楚。這次我們來(lái)回顧整理一下Junit的執(zhí)行流程,給出各種特性生效的機(jī)理,并分析一些代碼中精妙的地方。 Junit的執(zhí)行流程 JUnitCore的RunMain方法,使用jUn...
摘要:前言上次的博客中我們著重介紹了的機(jī)制,這次我們將聚焦到自定義擴(kuò)展上來(lái)。在很多情形下我們需要在測(cè)試過(guò)程中加入一些自定義的動(dòng)作,這些就需要對(duì)進(jìn)行包裝,為此提供了以接口和為基礎(chǔ)的擴(kuò)展機(jī)制。 前言 上次的博客中我們著重介紹了Junit的Validator機(jī)制,這次我們將聚焦到自定義擴(kuò)展Rule上來(lái)。在很多情形下我們需要在測(cè)試過(guò)程中加入一些自定義的動(dòng)作,這些就需要對(duì)statement進(jìn)行包裝,...
摘要:前言在上次的博客中我們提到了最終由以為參數(shù)執(zhí)行測(cè)試樣例,但并沒(méi)有解釋到底測(cè)試方法是如何被運(yùn)行起來(lái)的,一些諸如之類的特性又到底是如何實(shí)現(xiàn)的呢。這次我們就集中深入的運(yùn)行機(jī)制來(lái)探究樣例是如何被運(yùn)行的。使用拿到的直接運(yùn)行方法。 前言 在上次的博客中我們提到了最終由Runner以Notifier為參數(shù)執(zhí)行測(cè)試樣例,但并沒(méi)有解釋到底測(cè)試方法是如何被運(yùn)行起來(lái)的,一些諸如RunWith、RunAft...
閱讀 3146·2021-11-22 12:01
閱讀 3767·2021-08-30 09:46
閱讀 784·2019-08-30 13:48
閱讀 3209·2019-08-29 16:43
閱讀 1657·2019-08-29 16:33
閱讀 1848·2019-08-29 13:44
閱讀 1410·2019-08-26 13:45
閱讀 2228·2019-08-26 11:44