扩展JUnit4以促进测试驱动开发2011-10-02 ibm 左超简介:在采用测试驱动开发的项目中,有一个经常困扰开发者的问题是:当存在大量的测试用例时, 一次运行完所有的测试用例要花费很长的时间,采用 TestSuite 来组织测试用例的方式缺乏灵活性,通 常它的组织结构大体和 Java Package/Class 的组织结构类似,不能和当前实现的业务需求完全相关。本 文将通过扩展 JUnit4 来实现一种可以更加高效灵活地组织和运行测试用例的解决方案,促进测试驱动开 发实践更有效地进行。实际 Java 开发中单元测试常遇到的问题在敏捷开发中,为了提高软件开发的效率和质量,测试驱动开发实践已经被广泛使用。在测试驱动开 发的项目中,随着项目开发不断地深入,积累的测试用例会越来越多。测试驱动开发的一个最佳实践是随 时运行测试用例,保证任何时候测试用例都能成功执行,从而保证项目的代码是可工作的。当测试用例数 量很多时,一次运行所有测试用例所消耗的时间可能会很长,导致运行测试用例的成本很高。所以在实际 敏捷开发中,如何组织、运行测试用例以促进测试驱动开发成为一个值得探究的问题。JUnit 是 Java 开发中最常用的单元测试工具。在 JUnit3 用 TestSuite 来显式地组织想要运行的 TestCase,通常 TestSuite 的组织大体上和 Java Package/Class 的组织类似,但这样并不能和当前正 在实现的业务需求完全相关,显得比较笨拙,比如说要运行某个子模块下所有的 TestCase,或者运行跟 某个具体功能相关的 TestCase,涉及到的 TestCase 数量可能较多,采用定义 TestSuite 的方式一个个 地添加 TestCase 很低效并且繁琐。在 JUnit4 中同样只能显式地组织要运行的 TestCase。怎么样解决这些问题,新发布的 JUnit4 提供了开发人员扩展的机制,可以通过对 JUnit 进行扩展来 提供一种解决的方法。JUnit4 的新特性和扩展机制JUnit4 引入了 Java5 的 Annotation 机制,来简化原有的使用方法。测试用例不再需要继承 TestCase 类,TestSuite 类也取消了,改用 @Suite.SuiteClasses 来组织 TestCase。但是这种还是通 过显示指定 TestCase 来组织运行的结构,不能解决上述的问题。关于 JUnit4 的新特性具体可以参考 developerworks 的文章。JUnit4 的实现代码中提供了 Runner 类来封装测试用例的执行。它本身提供了 Runner 的多种实现, 比如 ParentRunner 类、Suite 类,BlockJUnit4ClassRunner 类。我们可以充分利用 JUnit4 提供的已 有设施来对它进行扩展,实现我们期望的功能。首先我们来分析一下 JUnit4 在运行一个测试用例时,它内部的核心类是如何工作的。图 1 展示了 JUnit4 运行测试用例时,核心类之间的调用关系。图 1. JUnit4 核心类之间的调用关系