循序渐进学习JUnit:第二部分

转载 2005年03月01日 17:56:00

利用Ant使测试自动化

如前面所述,测试运行器是非常原始的。如果你正在运行Ant来编译你的工程,那么编译文件是运行单元测试的好方法。(关于Ant的介绍,请参考我的文章《Ant简介》(Starting with Ant),发表于Oracle杂志2002年11/12月号中)。

假设你的源文件在src目录中,所生成的类在tmp目录中,并且junit.jar库位于工程的libdirectory目录中,那么你可以编译Java源文件,并使用清单3中所示的编译文件(在工程的根目录中)运行单元测试。

这个编译文件的核心是运行单元测试的测试目标。运行这些测试是这个目标junit的唯一任务。为了运行这一可选任务,必须首先将junit.jar库放到Ant安装目录下的lib目录中,然后下载并安装同一目录中的Ant可选任务库。清单3中的示例嵌套了一个classpath类,它包括JUnit库和工程的类;示例中还嵌套了一个batchtest元素,它利用一个选择适当源文件的fileset元素定义了将要运行的测试。这个任务还包括haltonfilure和haltonerror属性,它们告诉Ant在遇到一个失败或错误时是否应当停止。如果将它们的值设置为"真",那么Ant在遇到第一个失败或错误时将会停止,编译将会失败(显然,这表示在运行测试过程中存在有问题)。另一方面,如果将它们的值设置为"假",其结果就不是非常明确了(即使测试失败,编译也会成功),但所有测试仍将运行。printsummary属性指示Ant是否显示运行测试的输出。数值withOutAndErr可以在开发测试时方便地告诉Ant显示标准输出和错误输出。数值off表示不显示任何内容,而on只显示测试报告(没有测试类的输出)。junit任务具有很多属性,详细内容请参考Ant的文档。

为了测试这一编译文件,你需要建立名字为src、tmp和lib的目录。将junit.jar库放到lib目录中,并将前面看到的示例Java源文件放到src目录中。打开终端,进入该工程的根目录,并输入ant,其结果为:

$ ant
Buildfile: build.xml

clean:
   [delete] Deleting directory 
     /Users/casa/doc/oracle

     /junit/prj/tmp
   [mkdir] Created dir: /Users/casa
     /doc/oracle/junit/prj/tmp

bin:
    [javac] Compiling 4 source files 
      to /Users/casa/doc/oracle
      /junit/prj/tmp


test:
    [junit] Running IsoDateTest
    [junit] Tests run: 1, Failures: 
      0, Errors: 0, Time elapsed: 
           0,005 sec
    [junit] Running IsoDateTest2
    [junit] Tests run: 2, Failures: 0, 
      Errors: 0, Time elapsed: 0,031 sec
    [junit] Output:
    [junit] setUp()

    [junit] testIsoDate()
    [junit] tearDown()
    [junit] setUp()
    [junit] testToString()
    [junit] tearDown()

all:

BUILD SUCCESSFUL
Total time: 8 seconds

Ant还可以生成非常有用的HTML格式的测试报告。为了生成这样的报告,将前面的测试目标用以下目标代替:

<target name="test" depends="bin"
       description="Run JUnit tests">
  <junit haltonfailure="false"
        printsummary="withOutAndErr">
    <classpath refid="cp"/>
    <batchtest todir="${tmp}">
      <fileset dir="${src}" 
              includes="**/*Test*.java"/>
     </batchtest>

     <formatter type="xml"/>
  </junit>
  <junitreport todir="${tmp}">
    <fileset dir="${tmp}" 
            includes="TEST-*.xml"/>
    <report format="frames" 
           todir="${tmp}"/>
  </junitreport>
</target>

这一目标与前面的目标相同,只是该目标在batchtext元素中增加了一个新的属性--todir,它告诉Ant在tmp目录中生成可扩展的标记语言(XML)报告。该目标还增加了一个新的junitreport元素,以便由XML文件生成一个HTML报告。这一元素要求在安装Ant的lib目录中安装Xalan库(详细内容见Ant文档的junitreport部分:ant.apache.org/manual/install.html)。这一元素还定义了使用todir属性生成的文件的目标目录。通过嵌套一个fileset元素来定义为生成这一报告而需要处理的XML文件。期望的输出格式利用嵌套的报告元素来实现。该对象将生成一个诸如图4所示的报告。

这类报告在使单元测试自动运行时特别有用(比如在夜间编译期间)。在这些情况下,错误或失败不会中断测试,因此你必须将前面提到的junit任务的haltonfailure和haltonerror属性设置为"假"。这一报告对于衡量实施进程也非常有用(比如当你必须重写已有代码时,或者在实施之前已经编写了测试的情况下)。

Ant对启动JUnit图形运行器也非常有用。下面的对象将会启动Swing测试运行器:

<target name="testui" depends="bin"
        description="Run graphical JUnit">
<java classname="junit.swingui.TestRunner"
      classpathref="cp" 
      fork="true"/>
</target>

你应当在终端中运行这一对象,并且在另一个终端或你喜欢的IDE中使用Ant对其进行编译。这种方式使你不必在每次想要测试代码时都启动图形运行器。

在Oracle9i Jdeveloper中的JUnit集成

Oracle9i JDeveloper并没有基于网络集成JUnit,但是下载并安装这一插件只需要几分钟的时间。为了完成此过程,选择JDeveloper的"Help"菜单下的"Check for Updates"项。这样将会打开IDE更新向导,以连接到Oracle技术网站,下载该插件并安装它。当安装该插件后,需要关闭并重启Oracle9i JDeveloper。注意,向导还会下载相关的文档。

通过为每个任务提供向导,这个插件极大地提高了开发人员编写测试实例、测试包和fixture等的工作效率。要调用这些向导,点击"File"菜单下的"New"项,然后选择"General/Unit Tests"类,并从右侧的窗体中选择合适的向导。你也可以从界面上启动测试套件。

当准备好对项目进行代码测试后,应当首先使用专用向导来编写fixture,然后测试实例向导可以利用它们集成到测试实例中。另外,还有一些用来生成自定义测试fixture的向导以及生成商务组件和数据库连接测试fixture的向导。这后两种向导生成专用代码,以使用setUp()和tearDown()方法设置和发布商务组件或数据库连接。

当完成fixture后,下一步应当使用合适的向导来生成测试实例,这些向导可以让你选择要测试的类和方法。你还可以选择在这个测试中使用的fixture。这将生成一个使用测试方法的主体完成的代码框架。最后应当生成套件来运行你的测试。这个专用向导让你选择要包括在套件中的测试,并为你生成整个类。要启动一个测试套件,点击浏览器中的文件,并选择Run。这将会启动图形界面并运行套件的测试。

在"Help"菜单中选择"Help Topics",你将会在JDeveloper文档中找到关于如何使用这些向导的详细教程。这会打开帮助系统窗口。点击"Unit Testing with JUnit"项,然后选择合适的教程。

JUnit和JDeveloper之间的这种集成使你能够只编写单元测试中你感兴趣的那部分的代码,而让工具为你编写重复的代码。

下一步

访问JUnit网站
www.junit.org

下载
Oracle9i Jdeveloper
otn.oracle.com/software/products/jdev/

Oracle9i应用服务器
otn.oracle.com/software/products/ias/

学习Oracle9i JDeveloper扩展
otn.oracle.com/products/jdev/htdocs/partners/addins

阅读Oracle9i JDeveloper文档
otn.oracle.com/docs/products/jdev/

JUnit最佳实践

下面是一些在使用JUnit时应当注意的技巧:

  • 在实施之前编写测试代码。这是一种合同驱动的实施方式。
  • 只测试那些可能会中断的方法(也就是说,在多数情况下不应测试setter和getter方法)。要尽可能地多进行测试,以避免回归测试。当测试一个较大的应用程序时,你可以在夜间编译时运行所有测试。
  • 一定要使用正确的JUnit扩展来测试特殊的应用程序(如使用Castus测试J2EE应用程序)。

值得花费的时间

到现在,你应当已经清楚地知道使用JUnit框架和合适的工具实施单元测试是多么快速而简单。关于单元测试的下一个目标是使你的CTO相信你在实施测试时所必须花费的时间是为了以后节省更多的时间。但是,当你考虑在检查老代码、修正错误和发布一个调试过的版本上所花费的时间(它可能花费整个一天)时,在开发过程的早期阶段捕获的代码错误毫无疑问是一项很好的投资。这里并没有考虑当错误代码不再位于块的顶部时开发人员必须遵循的"black magic"步骤,这些步骤包括:标记代码,制作一个分支、修正代码错误、进行发布,以及将代码修正合并到块中。所有这些步骤都非常耗时,并且容易产生错误。

要开始使用单元测试和JUnit,请访问JUnit网站: www.junit.org。你将找到大量有用的文档(包括使用JUnit实施测试的详细说明书)、一个与JUnit集成的IDE列表,以及关于JUnit扩展工具的详细内容。

Michel Casabianca ( casa@sweetohm.net)是In-Fusio(一家为移动用户提供游戏服务的法国公司)的一名软件工程师,同时也是XML Pocket Reference(O'Reilly出版,2001年)一书的合著者。

表1:编写测试实例中所使用的判定方法

assertEquals(期望原型,实际原型) 检查两个原型是否相等
assertEquals(期望对象,实际对象) 利用对象的equals()方法检查两个对象是否相等
assertSame(期望对象,实际对象) 检查具有相同内存地址的两个对象是否相等
assertNotSame(期望对象,实际对象) 检查具有不同内存地址的两个对象是否不相等
assertNull(对象 对象) 检查一个对象是否为空
assertNotNull(对象 对象) 检查一个对象是否为非空
assertTrue(布尔条件) 检查条件是否为真
assertFalse(布尔条件) 检查条件是否为假

相关文章推荐

循序渐进学习JUnit

  • 2012年05月30日 15:43
  • 60KB
  • 下载

博主作品《循序渐进Linux》第二版出版发行啦(附封面和目录)

从《循序渐进Linux》第一版发布,到现在已经近6年了,6年的时间,技术发生了很大的变化,Linux系统的内核版本从2.6.9(RHEL4.x)已经更新到了现在的3.10(Centos7.x),第一版...

【SQL学习】——第二部分:从关系角度理解SQL

6. 从关系角度理解SQL 6.1. 关系和表 众所周知,我们目前所用的数据库,通常都是关系数据库。关系自然在其中处于关键位置。初学数据库原理的人可能会很困惑关系和表是什么联系,如...

《Python学习》 第二部分 类型与操作(三)

。。。

使用WSDL发布WebService(第二部分)简单对象访问协议——学习SOAP语法和使用SOAP发布WSDL

作者:Bilal Siddiqui (wap_monster@yahoo.com) CEO, WAP Monster 01 Mar 2002 译者:梅青松 注:由于时间和本人水平问题差错在所难...

《Python学习》 第二部分 类型与操作(二)

第五章  数值类型 1、Python中的数值并不是一个对象类型,而是多个相似的类型。 2、一个完整的Python数值工具箱包括: 整数和浮点数负数固定精度的十进制小数有理数(能写成分子分母同为整数...

《算法导论》学习总结——第二部分2优先级队列

如堆一样,队列也有2种,最大优先级队列和最小优先级队列。最大优先级队列的一个应用是在一台分时计算机上进行作业调度(终于搞到点有用的),对于最大优先级队列,支持以下操作:     1)INSERT(S,...

深入学习中央调度(GCD)--第二部分

更新说明:查阅我们基于iOS8.0和Swift下中央调度(http://www.raywenderlich.com/79150/grand-central-dispatch-tutorial-swif...

数据库系统概论 学习笔记(三)第二部分

3.4 數據更新3.4.1 插入數據(Insert Into)一、插入單個元組 格式:Insert Into [([,...)] values ([,]...); 說明:Into子句可以不指明任何列...

Linux 学习笔记 -- 第二部分 Linux 文件、目录与磁盘格式 -- 第7章 Linux 文件与目录管理

有趣的是,因为托瓦茨放置内核的那个FTP网站的目录为Linux,从此,大家便称这个内核为Linux了 对目录有执行权限(x)才能切换到目录内。 向上翻页: shift+PgUp 向...
  • tedpenk
  • tedpenk
  • 2014年06月26日 16:08
  • 252
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:循序渐进学习JUnit:第二部分
举报原因:
原因补充:

(最多只允许输入30个字)