zoukankan      html  css  js  c++  java
  • TestNG 在Java 单元测试中的使用

    TestNG 使 Java 单元测试轻而易举

    文章来源:http://www.ibm.com/developerworks/cn/java/j-testng/

    TestNG 快速起步

    TestNG 的测试类是普通的老式 Java 对象;您不需要扩展任何特殊的类,也不需要使用测试方法的任何命名约定:您只要用标注 @Test通知框架这个类的方法是测试。清单 1 演示了实用类 StringUtils的一个最简单的测试。它测试 StringUtils的两个方法: isEmpty()方法检测String是否为空; trim()方法从 String两端删除控制字符。请注意,其中使用了 Java 指令 assert来检测错误情况。

    清单 1. 针对类 StringUtils 的一个测试用例
     package tests; 
     import com.beust.testng.annotations.*; 
     import org.apache.commons.lang.StringUtils; 
     public class StringUtilsTest 
     { 
    	 @Test 
    	 public void isEmpty() 
    	 { 
    		 assert StringUtils.isBlank(null); 
    		 assert StringUtils.isBlank(""); 
    	 } 
    	 @Test 
    	 public void trim() 
    	 { 
    		 assert "foo".equals(StringUtils.trim("  foo   ")); 
    	 } 
     }

    但是,在运行测试之前,必须用特殊的 XML 文件配置 TestNG,习惯上把这个文件命名为 testng.xml。这个文件的语法非常简单,如清单 2 所示。这个文件首先定义测试套件 My test suite,这个套件只包含一个测试 First test,这个测试由 StringUtilsTest类完成。

    清单 2. TestNG 的配置文件
     <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > 
     <suite name="My test suite"> 
      <test name="First test"> 
        <classes> 
           <class name="tests.StringUtilsTest" /> 
        </classes> 
      </test> 
     </suite>

    如果这个示例 testng.xml 文件看起来没什么用处(只有一个测试类),那么好消息是:这实际上是您定义测试套件时 惟一需要编写的文件。还记得 JUnit 过去的日子么?在那些日子里,套件的定义可能分布在多个文件中:JUnit 的 TestSuite文件,属性文件,还有当然缺不了的 Ant 构建文件。使用 TestNG,所有必需的数据都集中在 testng.xml 文件中。不需要额外的 TestSuite文件和构建文件。

    要运行测试,请用 javac编译类,然后用以下命令调用 TestNG :

    java -ea -classpath .;testng.jar;commons-lang-2.0.jar com.beust.testng.TestNG testng.xml

    在这里,选项 -ea告诉 JVM 处理断言(在断言失败时抛出异常);运行这个例子只需要 testng.jar 和 commons-lang-2.0.jar 这两个库,而com.beust.testng.TestNG是 TestNG 的主类。对于所有那些已经非常高兴地忘记了 java和 javac的神秘语法的开发人员来说,还提供了一个有用的 Ant 任务。作为例子,清单 3 演示了本文发布的示例应用程序的 Ant 构建文件。请注意与类com.beust.testng.TestNGAntTask关联的 testng任务的定义,以及它在 test目标中相当简单的用法。

    清单 3. 带有 TestNG 任务的 Ant 构建文件
     <project name="sample" default="test" basedir="."> 
       <!-- COMPILE TESTS--> 
       <path id="cpath"> 
          <pathelement location="testng.jar"/> 
          <pathelement location="commons-lang-2.0.jar"/> 
       </path> 
       <target name="compile"> 
          <echo message="compiling tests"/> 
          <mkdir dir="classes"/> 
          <javac   debug="true"
             source="1.5" classpathref="cpath"
             srcdir="src" destdir="classes"/> 
       </target> 
       <!-- RUN TESTS--> 
       <taskdef name="testng"
          classname="com.beust.testng.TestNGAntTask"
          classpathref="cpath"/> 
       <path id="runpath"> 
          <path refid="cpath"/> 
          <pathelement location="classes"/> 
       </path> 
       <target name="test" depends="compile"> 
          <echo message="running tests"/> 
          <testng fork="yes" classpathref="runpath" outputDir="test-output"> 
             <fileset dir="src" includes="testng.xml"/> 
             <jvmarg value="-ea" /> 
          </testng> 
       </target> 
     </project>

    如果一切正常,那么应当在控制台中看到测试结果。而且,TestNG 还在当前目录下自动创建了一个叫做 test-output 的文件夹,并在其中创建了一份非常好的 HTML 报告。如果打开该报告并装入 index.html,就可以看到与图 1 中的页面类似的页面。

    图 1. TestNG 创建的 HTML 报告

    TestNG 创建的 HTML 报告

    定义测试组

    TestNG 另外一个有趣的特性是其定义测试组的能力。每个测试方法都可以与一个或多个组相关联,但可以选择只运行某个测试组。要把测试加入测试组,只要把组指定为 @Test标注的参数,使用的语法如下:

     @Test(groups = {"tests.string"})

    在这个具体的例子中,您声明:标注的方法属于 tests.string组。因为参数 groups是一个数组,所以可以指定多个组,组名之间用逗号分隔。例如,在示例应用程序中,您可以为 String、Number 以及 boolean 创建不同的测试,然后如清单 4 所示配置 TestNG, 有选择地运行它们 .

    清单 4. 带有不同组的配置文件
     <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > 
     <suite name="My suite"> 
      <test name="Simple example"> 
        <groups> 
          <run> 
    		 <include name="tests.string" /> 
    		 <include name="tests.math" /> 
    		 <exclude name="tests.boolean"/> 
          </run> 
        </groups> 
        <classes> 
    		 .... list classes here.... 
        </classes> 
      </test> 
     </suite>

    显然,当运行不同的测试组时,HTML 报告能够在单一列表中显示所有测试,也可以在独立的列表中显示每个组的测试,从而能够立即理解问题的来源。

     

    配置方法

    使用 TestNG,不仅可以指定测试方法,还可以用专门的标注 @Configuration指定类中的其他特定方法,这些方法叫做 配置方法。配置方法有四种类型:

    • beforeTestClass方法在类实例化之后,但是在测试方法运行之前执行。
    • afterTestClass方法在类中的所有测试方法执行之后执行。
    • beforeTestMethod方法在类中的任何测试方法执行之前执行。
    • afterTestMethod方法在类中的每个测试方法执行之后执行。

    图 2 进一步描述了测试类的生命周期。

    图 2. 测试类的生命周期
    测试类的生命周期

    清单 5 演示了配置方法的一些示例。请注意,如果您使用组,那么配置方法也必须属于某个组。而且,配置方法的四种类型彼此之间不是互斥的,所以可以把方法定义成同时属于一种或多种配置方法类型。(作为例子,请参阅清单 5 中的 aroundTestMethods()方法)。

    清单 5. 配置方法示例
     @Configuration(beforeTestClass = true, groups = {"tests.workflow"}) 
     public void setUp() 
     { 
       System.out.println("Initializing..."); 
     } 
     @Configuration(afterTestMethod = true, beforeTestMethod = true
        , groups = {"tests.workflow"}) 
     public void aroundTestMethods() 
     { 
       System.out.println("Around Test"); 
     }

    TestNG 中的配置方法是 JUnit 的 setUp()和 tearDown()方法的增强版;它们的主要目的是为测试创建正确的执行上下文,并在测试用例执行之后刷新数据。

     

    异常检测

    使用 TestNG,您可以非常简单、非常容易地检测异常的发生。很明显,用 JUnit 也可以做这件事,但是正如您在清单 6 中的示例中所看到的,使用 TestNG 的 @ExpectedExceptions标注可以使代码编写惊人地容易和简单。 @ExpectedExceptions标注指明框架能够容忍抛出的NumberFormatException异常,所以不应当被当作是故障。要查看在某行代码中是否抛出异常,您可以直接在这行代码之后加入 assert false语句。这意味着 只有在指定行中抛出特定类型的异常的时候,您才会通过测试。

    清单 6. 用 TestNG 进行异常检测
     public class  NumberUtilsTest 
     { 
    	 @Test(groups = {"tests.math"}) 
    	 @ExpectedExceptions(NumberFormatException.class) 
    	 public void test() 
    	 { 
    		 NumberUtils.createDouble("12.23.45"); 
    		 assert false;  //shouldn't be invoked 
    	 } 
     }
     
  • 相关阅读:
    图像
    链接
    列表
    常见的文本标签
    注释有哪些作用?你会用使用注释来做什么?
    如何使用浏览器查看源代码?查看源码的快捷方式是什么?
    编辑HTML源代码
    <html>,<head>,<body>,<title>的作用
    HTML中的标签和属性
    记录Git的安装过程
  • 原文地址:https://www.cnblogs.com/strongery/p/5320262.html
Copyright © 2011-2022 走看看