首先,从对象的创建上来分析。客户类负责创建Suite和aTestRunner。注意,类TestRunner含有一个静态函数Run(Test),它自创建本身,然后调用doRun()。客户类调用的一般是该函数,其代码如下:
static public void run(Test suite){ TestRunner aTestRunner= new TestRunner();//新建测试驱动 aTestRunner.doRun(suite, false);//用测试驱动运行测试集 }
Suite对象负责创建众多的测试案例,并将它们包容到本身。客户测试案例继承TestCase类,它将类,而不是对象传给Suite对象。Suite对象负责解析这些类、提取构造函数和待测试方法。以待测试方法为单位构造测试案例,测试案例的fName就是待测试方法名。测试结果集由aTestRunner创建。这似乎同先前阐述的类图有些矛盾,那里阐述了一个测试集可以包含很多个不同的测试驱动,似乎先创建结果集比较理想。显然,这里对测试结果的处理只采用了一种方式,所以这样做同样可行。
其次,从测试动作的执行上来分析,测试真正是从suite.run(result) 开始的。其代码如下:
其次,从测试动作的执行上来分析,测试真正是从suite.run(result) 开始的。其代码如下:
public void run(TestResult result){ //从案例集中获得所有测试案例,分别执行 for (Enumeration e= tests(); e.hasMoreElements(); ) { if (result.shouldStop() ) break; Test test= (Test)e.nextElement(); runTest(test, result); } }
一旦测试案例开始执行,首先使用一个回调策略将自身交由Result。这样做的每一步测试,测试驱动aTest Runner都可以跟踪处理。这无形中建立了一个庞大的监视系统,随时都可以对所发生的事件给予不同等级的关注。
我们分析一下涉及到的动作行为的设计模式:
1. Template Method (模板方法)类行为模式,它的实质就是首先建立方法的骨架,而尽可能地将方法的具体实现向后推移。TestCase.runBare()就采用了这种模式,客户类均可以重载它的三个方法,这样使得测试的可伸缩性得到提高。
我们分析一下涉及到的动作行为的设计模式:
1. Template Method (模板方法)类行为模式,它的实质就是首先建立方法的骨架,而尽可能地将方法的具体实现向后推移。TestCase.runBare()就采用了这种模式,客户类均可以重载它的三个方法,这样使得测试的可伸缩性得到提高。
2. Command (命令)对象行为模式,其实质就是将动作封装为一个对象,而不关心动作的接收者。这样动作的接收者可以一直到动作具体执行时才需确定。接口Test就是一个Command集,使得不同类的不同测试方法可以通过同一种接口Test构造其框架结构。这样对测试的集成带来了很多方便。public void runBare() throws Throwable{ setUp(); try {runTest();} finally {tearDown();} }