参考:JUnit源码解读
JUnit 是由 Erich Gamma 和 Kent Beck 编写的一个开源的单元测试框架。它属于白盒测试,只要将待测类继承 TestCase 类,就可以利用 JUnit 的一系列机制进行便捷的自动测试了。
JUnit 的设计精简,易学易用,但是功能却非常强大,这归因于它内部完善的代码结构。 Erich Gamma 是著名的 GOF1 之一,因此 JUnit 中深深渗透了扩展性优良的设计模式思想。 JUnit 提供的 API 既可以让您写出测试结果明确的可重用单元测试用例,也提供了单元测试用例成批运行的功能。在已经实现的框架中,用户可以选择三种方式来显示测试结果,并且显示的方式本身也是可扩展的。
JUnit 的完整生命周期分为 3 个阶段:初始化阶段、运行阶段和结果捕捉阶段。下面就从这三个阶段详细分析源代码。
初始化阶段
初始化的入口有三个,分别是
- junit.textui.TestRunner
- junit.swingui.TestRunner
- junit.awtui.TestRunner
他们的不同就是ui不同,下面以textui为例:
package com.my.test;
import junit.framework.TestResult;
import junit.textui.TestRunner;
public class TextUiTest {
public static void main(String[] args) {
TestRunner runner = new TestRunner();
try {
TestResult result = runner.start(args);
if(!result.wasSuccessful()) {
System.exit(TestRunner.FAILURE_EXIT);
}
System.exit(TestRunner.SUCCESS_EXIT);
} catch (Exception e) {
e.printStackTrace();
System.exit(TestRunner.EXCEPTION_EXIT);
}
}
}
start函数所做的事就是将传入的参数中的类名提取出来(也就是你要测试哪个类)存在testcase中,并且根据你传入的参数确定运行模式(runSingleMethod
或者doRun
)
public TestResult start(String[] args) throws Exception {
String testCase = "";
String method = "";
boolean wait = false;
...
if (testCase.equals("")) {
throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
}
try {
if (!method.equals("")) {
return runSingleMethod(testCase, method, wait);
}
//初始化
Test suite = getTest(testCase);
return doRun(suite, wait);
} catch (Exception e) {
throw new Exception("Could not create and run test suite: " + e);
}
}
拿到testcase2后,就调用getTest方法。
public