博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Junit源码阅读(一)
阅读量:6518 次
发布时间:2019-06-24

本文共 3809 字,大约阅读时间需要 12 分钟。


Junit的工程结构

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中的依赖关系

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运行时序图

JUnitCore使用外观模式(facade),对外提供一致的界面,同时支持运行JUnit 4或JUnit 3.8.x用例,通过命令行执行用例.首先它使用jUnitCommandLineParseResult解析外部参数,将默认的TextListener加入内置的Notifier。它所运行的Runner也是由jUnitCommandLineParseResult提供的,先行通过测试filter掉不需要的样例,最后调用Runner的run方法。

转载地址:http://eqrfo.baihongyu.com/

你可能感兴趣的文章
unity3d游戏开发学习之使用3dmax创建导弹模型
查看>>
hadoop调度程序时出现“Error opening job jar”错误
查看>>
CentOS安装python-pip
查看>>
jquery $.post用法
查看>>
boost库在工作(15)绑定器与函数对象之三
查看>>
【noip模拟题】迎接仪式(dp+特殊的技巧)
查看>>
C/C++产生随机数
查看>>
android WebView总结
查看>>
How to get blob data using javascript XmlHttpRequest by sync
查看>>
Asynchronous Programming Using Delegates使用委托进行异步编程
查看>>
代码是写给人看的,不是写个机器看的
查看>>
sina微博上看到的关于android界面设计相关的规范
查看>>
STL笔记(2) STL之父访谈录
查看>>
heartbeat测试
查看>>
STL——空间的配置和释放std::alloc(第一级配置器和第二级配置器)
查看>>
微软职位内部推荐-Senior Software Engineer II-Search
查看>>
PHP 的解压缩ZipArchive中的extractTo()方法 LINUX+nginx环境中解压zip时文件丢失的问题...
查看>>
ylbtech-LanguageSamples-ExplicitInterface(显示接口)
查看>>
RapeLay(电车之狼R)的结局介绍 (隐藏结局攻略)
查看>>
Google Mesa概览
查看>>