网络通信 频道

科达TrueSens在2007多媒体视讯高峰论坛上大放异彩

JUnit的Exception的抛出机制

 JUnit的异常层次分为三层:1.Failure,客户预知的测试失败,可以被Assert方法检测到;2. Error,客户测试的意外造成的;3.Systemerror, JUnit的线程死亡级异常,这种情况一般很少发生。JUnit的这三种异常在TestResult类的RunProtected()方法得到很好体现。这里用Protectable接口封装了Test的执行方法,其实p.protect执行的就是test.runBare()。
public void runProtected(final Test test, Protectable p){    try {p.protect();}    catch (AssertionFailedError e)     {addFailure(test, e);}    catch (ThreadDeath e)    {rethrow e;}    catch (Throwable e)    {addError(test, e);} }

    代码首先检查是否是Assertion FailedError,然后判断是否是严重的ThreadDeath。这种异常必须Rethrow,才能保证线程真正的死亡,如果不是,说明它是一种意外。

 前两种异常均保存在测试结果集中,等到整个测试完成,依次打印出来供客户参考。

实施JUnit的几点建议

 从以上的分析中,可以了解JUnit的结构和流程,但是在实际应用JUnit时,有几点建议还需要说明,如下:

 1. 客户类可以重载runTest(),它的缺省实现是调用方法名为fName的测试方法。如果客户不是使用TestSuite加载TestCase,就尤其需要对其重载,当然这种方式并不赞成使用,不利于集成。另外,setUp()和tearDown()的功能似乎与构造函数雷同,但如果测试案例之间具有类继承关系,采用构造函数初始化一些参数就会造成数据的混乱,不利于判定测试结果的有效性。

 2. 待测试函数的调用顺序是不确定的,采用的数据结构是Vector()。如果需要有顺序关系,可以将它们组合到一起,然后用同一个测试方法。

 3. 为了使测试结果清晰明了,程序中最好不要有打印输出,要么程序的打印输出与JUnit测试的打印输出不要用同一个数据源System.out。其实这是两种测试习惯,直接打印输出是较传统的,从测试动机上考虑它也是较随意的,并且结果需要人工观察。如果直接打印输出较多的话,观察者可能无法获得满意的结果。

  此外,如何扩展这个测试框架呢? junit.extensions包给出了几点提示。我们可以使用junit.extensions. ActiveTest在不同的线程中运行一个测试实例。 对于要对测试案例添加新的功能可以采用Decorator模式,可以参考junit.extensions.TestDecorator以及它的子类junit.extensions.TestSetup、junit.extensions.RepeatedTest。这些仅仅提供了一些拓宽的思路,涉及到具体测试目标,还需进一步地挖掘。 

0
相关文章