`
jgnan
  • 浏览: 87573 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JUnit 4.7学习笔记(五)——测试引擎综述

阅读更多
今天突然很想写JUnit的学习笔记,所以找回以前的文章接着写了:
自从JUnit上升到4.1版本之后,开始全面支持JDK1.5的Annotation。另外也重写了它的测试引擎,实现了测试引擎的可定制话。当时给我一个全新的测试体验,从来没想过原来写测试用例也可以这么好玩。

先看下面的例子:
package com.amway.training.junit.runners;

import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;

/**
 * A Demo Test Runner
 * @author JJ
 *
 */
public class DemoRunner extends Runner {
	/**
	 * 核心引擎要求每个Runner类必须有一个这样的构造函数
	 * @param testClass 测试类
	 */
	public DemoRunner(Class<?> testClass)
	{
	}
	
	@Override
	public Description getDescription() {
		return Description.EMPTY;
	}

	@Override
	public void run(RunNotifier notifier) {
		System.out.println("Hello, JUnit!");
	}

}


然后写一个测试:
package com.amway.training.junit;

import org.junit.runner.RunWith;

import com.amway.training.junit.runners.DemoRunner;

@RunWith(DemoRunner.class)
public class TestDemoRunner {

}


运行这个单元测试,你会发现我们执行了DemoRunner的Run方法。说明我们现在可以改变测试运行的行为。

看了一下,发现4.7的这部分还是和4.1的时候发生了不少变化。首先,现在多了一个ParentRunner的类,它把Runner类再重新封装了一轮,并且让新的默认引擎类都继承于它。

上面的这些类就是4.7的Runner引擎家族。Junit38ClassRunner旁支是为了向下兼容3.8版本的测试用例。

IgnoredClassRunner会在测试引擎核心探测到测试文件的class有定义@Ignore注解的时候自动调用,它会跳过当前测试类的运行:
package com.amway.training.junit.runners;

import org.junit.Ignore;
import org.junit.Test;

@Ignore
public class TestIgnoredRunner {

	@Test public void testMethod1()
	{
		System.out.println("Hello");
	}
}


上例执行后,发觉运行结果并未对testMethod1进行执行。


而对于这部分的封装JUnit是通过Request机制来完成的。关于Request的介绍我们会在日后介绍(遥遥无期,遥遥无期。。。 )。

然后ErrorReportingRunner是在org.junit.internal包里面的,一般不会直接调用而是由系统的核心引擎去调用,所以它里面没有注释。我们来看看其源码以进行Runner的进一步学习:

首先,看其直接实现Runner的两个抽象方法:
	@Override
	public Description getDescription() {
		Description description= Description.createSuiteDescription(fTestClass);
		for (Throwable each : fCauses)
			description.addChild(describeCause(each));
		return description;
	}

	@Override
	public void run(RunNotifier notifier) {
		for (Throwable each : fCauses)
			runCause(each, notifier);
	}


然后可以知道其核心方法应该是runCause(Throwable,RunNotifier)
        private void runCause(Throwable child, RunNotifier notifier) {
		Description description= describeCause(child);
		notifier.fireTestStarted(description);
		notifier.fireTestFailure(new Failure(description, child));
		notifier.fireTestFinished(description);
	}


从字面看,可以知道这个测试引擎的主要工作就是把异常转换为Failure测试结果显示。以下是一个使用的例子:
            try {
			Runner runner= fRequest.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(), fRequest.toString())));
		}


核心的BlockJUnit4ClassRunner就不说了,Theories会在日后说,因为这个模块是Junit开发团队用来做实验的,里面的东西不适宜用于生产,不过适宜拿来玩:)

今天到此为止,先开个头,下次再说ParentRunner及下面还没介绍到的子类(因为事忙,今天要写到这里了)
  • 大小: 19.5 KB
  • 大小: 119.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics