junit4.12源码分析-启动到选择runner

  第一次写源代码分析,介绍运行流程和其中重要的类和接口!

  JUnitCore

  JUnitCore采用门面模式,可以启动junit4,junit3测试,也可以测试指定class。JUnitCore声明RunNotifier类,该类采用观察者模式实现事件管理。RunListener为测试事件基类,有测试开始结束失败等事件,如果想自定义事件可以继承该类。默认增加了两个RunListener,一个是TextListener,另一个是Result类函数createListener构造的Listener用于记录开始结束时间、执行总数、失败总数等。可看到run方法调用前触发了fireTestRunStarted,执行后触发了fireTestRunFinished。关键代码(截取)

    private final RunNotifier notifier = new RunNotifier();

    Result runMain(JUnitSystem system, String... args) {
        RunListener listener = new TextListener(system);
        addListener(listener);

        return run(jUnitCommandLineParseResult.createRequest(defaultComputer()));
    }

    public Result run(Request request) {
        return run(request.getRunner());
    }

    public Result run(Runner runner) {
        Result result = new Result();
        RunListener listener = result.createListener();
        notifier.addFirstListener(listener);
        try {
            notifier.fireTestRunStarted(runner.getDescription());
            runner.run(notifier);
            notifier.fireTestRunFinished(result);
        } finally {
            removeListener(listener);
        }
        return result;
    }

  Request

  对class和test的封装,可以是一个class下所有test、所有class下所有test、还可以结合filter。classes方法获取suite,suite里包含各个类的runner。关键代码(截取)

    public static Request classes(Computer computer, Class<?>... classes) {
        try {
            AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(true);
            Runner suite = computer.getSuite(builder, classes);
            return runner(suite);
        } catch (InitializationError e) {
            throw new RuntimeException(
                    "Bug in saff‘s brain: Suite constructor, called as above, should always complete");
        }
    }

  RunnerBuilder

  创建runner采用builder模式,对于每一个class产生一个runner。

    private List<Runner> runners(Class<?>[] children) {
        ArrayList<Runner> runners = new ArrayList<Runner>();
        for (Class<?> each : children) {
            Runner childRunner = safeRunnerForClass(each);
            if (childRunner != null) {
                runners.add(childRunner);
            }
        }
        return runners;
    }

  AllDefaultPossibilitiesBuilder

  选择具体builder,默认为junit4Builder,如果class有@Ignore标注则为IgnoredBuilder,如果class有@RunWith标注则为IgnoredBuilder,如果测试方法有suite则为SuiteMethodBuilder,如果class继承于junit.framework.TestCase则为JUnit38ClassRunner,否则默认时用JUnit4Builder返回BlockJUnit4ClassRunner

    public Runner runnerForClass(Class<?> testClass) throws Throwable {
        List<RunnerBuilder> builders = Arrays.asList(
                ignoredBuilder(),
                annotatedBuilder(),
                suiteMethodBuilder(),
                junit3Builder(),
                junit4Builder());

        for (RunnerBuilder each : builders) {
            Runner runner = each.safeRunnerForClass(testClass);
            if (runner != null) {
                return runner;
            }
        }
        return null;
    }
时间: 2024-11-05 15:59:52

junit4.12源码分析-启动到选择runner的相关文章

junit4.12源码分析-runner执行顺序

filter.sort runner执行要先过滤和排序.默认的filter是ALL代表全部通过,默认的排序是MethodSorter的DEFAULT ParentRunner调用filter和sort方法: public void filter(Filter filter) throws NoTestsRemainException { synchronized (childrenLock) { List<T> children = new ArrayList<T>(getFilt

Symfoy2源码分析——启动过程2

上一篇分析Symfony2框架源码,探究Symfony2如何完成一个请求的前半部分,前半部分可以理解为Symfony2框架为处理请求做准备工作,包括container生成.缓存.bundls初始化等一些列准备工作(Symfoy2源码分析——启动过程1).而这一篇讲的是Symfony2如何根据请求的数据生成Response对象,向客户端返回响应数据. 在分析前需要了解Symfony2的事件驱动机制:Symfony2事件驱动. 言归正传,Symfony2请求的工作流程其实是Symfony2内核的事件

TOMCAT源码分析(启动框架)

建议: 毕竟TOMCAT的框架还是比较复杂的, 单是从文字上理解, 是不那么容易掌握TOMCAT的框架的. 所以得实践.实践.再实践. 建议下载一份TOMCAT的源码, 调试通过, 然后单步跟踪其启动过程. 如果有不明白的地方, 再来查阅本文, 看是否能得到帮助. 我相信这样效果以及学习速度都会好很多! 1. Tomcat的整体框架结构 Tomcat的基本框架, 分为4个层次. Top Level Elements: Server Service Connector HTTP AJP Conta

Zookeeper 源码分析-启动

Zookeeper 源码分析-启动 博客分类: Zookeeper 本文主要介绍了zookeeper启动的过程 运行zkServer.sh start命令可以启动zookeeper.入口的main函数在类中QuorumPeerMain. main函数主要调用了runFromConfig函数,创建了QuorumPeer对象,并且调用了start函数,从而启动了zookeeper. Java代码   public class QuorumPeerMain { protected QuorumPeer

基于TCP网络通信的自动升级程序源码分析-启动升级文件下载程序

升级程序启动后,首先会连接服务器 private void Connect() { try { int port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"]); connnectionInfo = new ConnectionInfo(IPAddress, port); connection = TCPConnection.GetConnection(connnectionInfo)

Tomcat7.0源码分析——启动与停止服务

前言 熟悉Tomcat的工程师们,肯定都知道Tomcat是如何启动与停止的.对于startup.sh.startup.bat.shutdown.sh.shutdown.bat等脚本或者批处理命令,大家一定知道改如何使用它,但是它们究竟是如何实现的,尤其是shutdown.sh脚本(或者shutdown.bat)究竟是如何和Tomcat进程通信的呢?本文将通过对Tomcat7.0的源码阅读,深入剖析这一过程. 由于在生产环境中,Tomcat一般部署在Linux系统下,所以本文将以startup.s

Tomcat7.0源码分析——启动与停止服务原理

前言 熟悉Tomcat的工程师们,肯定都知道Tomcat是如何启动与停止的.对于startup.sh.startup.bat.shutdown.sh.shutdown.bat等脚本或者批处理命令,大家一定知道改如何使用它,但是它们究竟是如何实现的,尤其是shutdown.sh脚本(或者shutdown.bat)究竟是如何和Tomcat进程通信的呢?本文将通过对Tomcat7.0的源码阅读,深入剖析这一过程. 由于在生产环境中,Tomcat一般部署在Linux系统下,所以本文将以startup.s

Tomcat源码分析——启动与停止服务

前言 熟悉Tomcat的工程师们,肯定都知道Tomcat是如何启动与停止的.对于startup.sh.startup.bat.shutdown.sh.shutdown.bat等脚本或者批处理命令,大家一定知道改如何使用它,但是它们究竟是如何实现的,尤其是shutdown.sh脚本(或者shutdown.bat)究竟是如何和Tomcat进程通信的呢?本文将通过对Tomcat7.0的源码阅读,深入剖析这一过程. 由于在生产环境中,Tomcat一般部署在Linux系统下,所以本文将以startup.s

【JUnit4.10源码分析】6.1 排序和过滤

abstract class ParentRunner<T> extends Runner implements Filterable,Sortable 本节介绍排序和过滤. (尽管JUnit4.8.2源码分析-6.1 排序和过滤中演示了客户使用排序和过滤的方式,也有些不明确其设计意图.可是.先读懂源码为妙.说不定看着看着就明确了. ) org.junit.runner.manipulation包 排序和过滤的相关类型.在org.junit.runner.manipulation包中.Sort