测试驱动运行阶段(运行所有 TestXXX 型的测试方法)
由图 7 所示 , 我们可以知道初始化完毕,即 testsuit() 创建好后 , 便进入方法 :
doRun(suite, wait); |
代码如下 :
图 14. doRun 函数代码
该方法为测试的驱动运行部分,结构如下:
·创建 TestResult 实例。
·将 junit.textui.TestRunner 的监听器 fPrinter 加入到 result 的监听器列表中。
其中,fPrinter 是 junit.textui.ResultPrinter 类的实例,该类提供了向控制台输出测试结果的一系列功能接口,输出的格式在类中定义。 ResultPrinter 类实现了 TestListener 接口,具体实现了 addError、addFailure、endTest 和 startTest 四个重要的方法,这种设计是 Observer 设计模式的体现,在 addListener 方法的代码中:
public synchronized void addListener(TestListener listener) { fListeners.addElement(listener); } |
将 ResultPrinter 对象加入到 TestResult 对象的监听器列表中,因此实质上 TestResult 对象可以有多个监听器显示测试结果。第三部分分析中将会描述对监听器的消息更新。
计时开始。
run(result) 测试运行。
计时结束。
统一输出,包括测试结果和所用时间。
其中最为重要的步骤为 run(result) 方法,代码如下。
图 15. run 函数代码
Junit 通过 for (Enumeration e= tests(); e.hasMoreElements(); ){ …… } 对 TestSuite 中的整个“树结构”递归遍历运行其中的节点和叶子。此处 JUnit 代码颇具说服力地说明了 Composite 模式的效力,run 接口方法的抽象具有重大意义,它实现了客户代码与复杂对象容器结构的解耦,让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器。每次循环得到的节点 test,都同 result 一起传递给 runTest 方法,进行下一步更深入的运行。
图 16. junit.framework.TestResult.run 函数代码