补:Junit3执行流程分析
1、TestRunner 入口点。生成TestRunner实例,首先执行TestRunner的main方法。
public static void main(String args[]) {
TestRunner aTestRunner= new TestRunner();
try {
//args参数指定的测试类的名称
TestResult r= aTestRunner.start(args);
} catch(Exception e) {}
}
2、构造生成TestSuite 。suite的概念在于,一个测试类存在多个测试方法,将所有的测试方法抽取存储于一个集合,遍历执行对应操作。
/**
* Starts a test run. Analyzes the command line arguments and runs the given
* test suite.
*/
public TestResult start(String args[]) throws Exception {
String testCase= args[i]; // 赋值“测试类”名称
String method= "";
boolean wait= false;
try {
//判断是否执行单个方法的测试
if (!method.equals(""))
return runSingleMethod(testCase, method, wait);
//构造生成TestSuite
Test suite= getTest(testCase);
//执行测试
return doRun(suite, wait);
} catch (Exception e) {}
}
3、TestRunner继承BaseTestRunner,getTest()是BaseTestRunner定义的一个模版方法
/**
* Returns the Test corresponding to the given suite. This is
* a template method, subclasses override runFailed(), clearStatus().
*/
public Test getTest(String suiteClassName) {
Class testClass= null;
try {
//根据类名加载“测试类”
testClass= loadSuiteClass(suiteClassName);
} catch (ClassNotFoundException e) {}
catch(Exception e) {}
Method suiteMethod= null;
try {
//Junit3中可以自定义suite()方法,根据反射尝试获取suite方法对于的Method类
suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
} catch(Exception e) {
// try to extract a test suite automatically
clearStatus();
//若不存在suite方法,则构造Junit自动构造测试方法集合suite,返回。
return new TestSuite(testClass);
}
}
4、正式构造TestSuite
/**
* Constructs a TestSuite from the given class. Adds all the methods
* starting with "test" as test cases to the suite.
*/
public TestSuite(final Class theClass) {
fName= theClass.getName();
Class superClass= theClass;
Vector names= new Vector();
//遍历方法,判断是否为“需要测试”方法,构造
while (Test.class.isAssignableFrom(superClass)) {
Method[] methods= superClass.getDeclaredMethods();
for (int i= 0; i < methods.length; i++) {
addTestMethod(methods[i], names, theClass);
}
//获取到“父”类,一层层的向上遍历,找寻“Test”方法,添加到TestSuite
superClass= superClass.getSuperclass();
}
if (fTests.size() == 0)
addTest(warning("No tests found in "+theClass.getName()));
}
private void addTestMethod(Method m, Vector names, Class theClass) {
String name= m.getName();
//判断出来,添加进MethodName的集合names
if (names.contains(name))
return;
if (! isPublicTestMethod(m)) {
if (isTestMethod(m))
addTest(warning("Test method isn't public: "+m.getName()));
return;
}
names.addElement(name);
// createTest()根据 theClass与name(即方法名),为每个方法构造独立的TestCase的实例,指定TestCase的fName为name值,存储此TestCase于TestSuite
//就是说 :一个类有很多的需要测试方法,为每一个测试方法生成一个自身的实例,向上转型为TestCase,给TestCase的属性fName赋值为对应测试方法的名称
addTest(createTest(theClass, name));
}
5、准备执行测试
public TestResult doRun(Test suite, boolean wait) {
TestResult result= createTestResult(); //TestResult存储所有的执行结果信息
result.addListener(fPrinter); //添加监听器
long startTime= System.currentTimeMillis();
suite.run(result); //实际执行
long endTime= System.currentTimeMillis();
long runTime= endTime-startTime;
fPrinter.print(result, runTime);
return result;
}
6、开始执行
/**
* Runs the tests and collects their result in a TestResult.
*/
public void run(TestResult result) {
//遍历执行所有的测试
for (Enumeration e= tests(); e.hasMoreElements(); ) {
if (result.shouldStop() )
break;
Test test= (Test)e.nextElement();
runTest(test, result);
}
}
/**
* Runs the bare test sequence.
* @exception Throwable if any exception is thrown
*/
public void runBare() throws Throwable {
Throwable exception= null;
setUp(); //每个测试方法执行前执行的setUp()
try {
runTest(); //执行测试方法
} catch (Throwable running) {
exception= running;
}
finally {
try {
tearDown();//tearDown写在finally不论怎么样,在测试执行结束都会执行
} catch (Throwable tearingDown) {
if (exception == null) exception= tearingDown;
}
}
if (exception != null) throw exception;
}
7、通过反射执行实际的测试方法
/**
* Override to run the test and assert its state.
* @exception Throwable if any exception is thrown
*/
protected void runTest() throws Throwable {
assertNotNull(fName); // Some VMs crash when calling
Method runMethod= null;
try {
// use getMethod to get all public inherited
// methods. getDeclaredMethods returns all
// methods of this class but excludes the
// inherited ones.
//根据反射取得对应方法的Method类
runMethod= getClass().getMethod(fName, (Class[])null);
} catch (NoSuchMethodException e) {}
try {
//通过反射实际执行测试方法
runMethod.invoke(this, (Object[])new Class[0]);
}
catch (InvocationTargetException e) {}
}
8、实际的测试方法
public void testAdd() {
Arithmetic a = new Arithmetic();
int expected = 3;
assertEquals("失败", expected, a.add(1, 2));
}
9、执行Assert
/**
* Asserts that two ints are equal. If they are not
* an AssertionFailedError is thrown with the given message.
*/
static public void assertEquals(String message, int expected, int actual) {
assertEquals(message, new Integer(expected), new Integer(actual));
}
10、最终的错误的捕捉,以及测试结果打印。通过TestResult实现。
总结 :觉得和很多人说的那样,Junit更多体现的是优秀的设计思想。可惜自己现在还没有领悟到这步,只能简单的对整个的执行流程有初步的认识。继续努力。
分享到:
相关推荐
- 测试工具:如JUnit、Selenium,用于自动化测试。 - 部署工具:如Docker、JClouds,用于应用部署。 - 代码质量检查:如Checkstyle、PMD,用于代码质量管理。 - 持续交付/部署:如Pipeline,用于定义和执行持续...
《EShop网上商城系统.V1.1 - 基本流程》是一个基于Java技术的实践学习案例,旨在帮助开发者理解并掌握如何构建一个简单的电子商务平台。这个系统通过控制台模拟了用户在商城中的购物体验,从浏览商品到完成支付的...
【单元测试】是软件开发过程中的重要环节,它主要用于验证代码的各个独立模块是否按预期工作。本资料包由ZTE(中兴)提供,包含了关于单元测试的多个文档和教程,适合Java开发者学习和参考。 《JAVA单元测试(公司...
1. **任务驱动**:Ant的工作基于一系列的任务(tasks),每个任务执行特定的操作,如编译源代码、打包JAR文件或运行测试。 2. **依赖管理**:Ant可以跟踪项目中的文件依赖,确保在构建过程中按照正确的顺序执行操作...
- **白盒测试**:通过测试内部结构或工作流程来查找代码中的错误。 - **黑盒测试**:仅基于程序的功能需求规格说明,完全不考虑程序内部结构和内部特性。 ##### 2.2 测试的内容 单元测试通常包括以下内容: - **...
8. **测试和支持库**:开发过程中可能还包括一些测试和工具库,如`junit-*.jar`用于单元测试,`commons-lang3-*.jar`提供通用语言功能,`commons-io-*.jar`处理I/O操作。 综上所述,这个压缩包提供的jar文件涵盖了...
开发过程中,利用内置的 Javadoc 和 JUnit 支持,可以方便地编写、测试和调试 Java 代码。 **6. 性能优化** OpenJDK 不断优化性能,18.0.1.1 版本可能包含了一些针对 macOS 平台的特定优化。开发者可以使用 `-XX:+...
日常工作中,接口测试的工作流程可能更侧重于: - 定期维护测试环境; - 更新和优化测试用例; - 执行定期的回归测试; - 监控持续集成过程中的异常情况。 #### 5. 接口测试的技术简介 本节将简要介绍几种常用的...
相比于JUnit3,JUnit4最大的改进在于引入了注解(Annotations),这使得测试代码变得更加简洁且易于维护。 **1.1 注解的引入** - **注解简介**:在JUnit4中,注解是一种特殊的Java语法特性,用于描述源代码的元...
- **持续集成**:将JUnit测试整合到持续集成流程中,可以在每次提交代码后自动运行测试,及时发现潜在问题。 **1.2 环境配置** 本节将详细介绍如何在Eclipse环境中配置JUnit测试环境。 **1.2.1 下载JUnit包** ...
AntUnit借鉴了JUnit的模式,但将其集成到Ant的构建流程中,允许开发者在构建过程中运行单元测试,确保代码质量。AntUnit的任务可以嵌入到Ant构建脚本中,这样每次构建时,测试都会自动执行,从而及时发现潜在的问题...
- 自动化测试:可以创建和执行预定义的测试套件,减少手动工作。 - 请求构造器:允许用户构建和编辑SOAP或RESTful请求,包括设置HTTP头、查询参数等。 - 结果分析:显示详细的响应信息,包括HTTP状态码、响应时间...
JUnit属于白盒测试类型,允许开发者编写测试用例来验证程序各个部分是否按照预期工作。 **项目主页**:http://www.junit.org/ **下载地址**: - https://github.com/KentBeck/junit/downloads - ...
##### 1.1 为什么使用自动化测试? - **快速(Fast)**:自动化测试能够显著减少测试时间,尤其是在频繁迭代的环境中。 - **可靠(Reliable)**:通过自动化测试,可以避免人为错误,提高测试结果的准确性。 - **可...