使用 TestNG 的新特性管理实际项目中的大量单元测试

   随着项目的成长,单元测试的数量会迅猛增长。这就带来不少问题。首先数量巨大的单元测试难于管理,运行一遍耗时巨大。其次,有时某个微小改动可能只需要运行某个测试文件中的部分单元测试就可以,这时重新运行全部测试用例就没有必要了。其三,大多数项目需要用到多线程特性,为使用了多线程特性的代码写测试用例相当麻烦且容易出错。本文将利用 TestNG 提供的新特性,解决以上提到的问题。
TestNG 的示例代码

        TestNG 提供了从命令行运行测试用例的方法。下面将首先从命令行运行测试用例。假设有如下的测试用例组:

列表 1. TestNG 示例代码
    
package example1;

import org.testng.annotations.*;

public class SimpleTest {

  @Configuration(beforeTestClass = true)
  public void setUp() {
    // code that will be invoked when this test is instantiated
  }

  @Test(groups = { "HelloWorld" })
  public void helloWorldTest() {
    System.out.println("Hello World");
    throw new Error();
  }

  @Test(threadPoolSize = 10, invocationCount = 5,  timeOut = 1000, groups = { "multiple" })
  public void multiThreadTest() {
     System.out.println("MultiThread test");
  }

  @Test(groups = { "HelloNature" })
  public void helloNatureTest() {
     System.out.println("Hello Nature");
     throw new Error();
  }
}      
运行 TestNG 的 Ant 脚本

为了运行这组测试用例,构建了如下的 Ant 运行脚本:
列表 2. 运行测试用例组的 Ant 脚本 build.xml 文件
    
<project default="test">

  <path id="cp">
    <pathelement location="c:/spark/eclipse/plugins/org.testng.eclipse_4.7.0.0/lib/testng-jdk15.jar"/>
    <pathelement location="c:\"/>
  </path>
 
  <taskdef name="testng" classpathref="cp"
           classname="org.testng.TestNGAntTask" />

 <target name="test">
    <testng classpathref="cp" groups="HelloWorld, HelloNature">
      <classfileset dir="./" includes="example1/*.class"/>
    </testng>
  </target>
 
</project>
 
运行之后的结果如下:
                                            图 1. 命令行运行 TestNG 的结果

                            
        运行完成之后,会在运行目录下生成一个test-output 目录。如图 2 所示:
                                                   图 2. 生成的 test-output 目录

                           

        该目录中包含有 html 形式的运行结果的报告,通过命令 start test-output\index.html 可以查看生成的测试报告。

图 3. 生成的测试报告

                      

        该目录中有一个 testng-failed.xml 文件,该文件可以被用来运行前一次运行失败的所有测试用例。下文将会详细介绍使用该文件的步骤。

重新运行前次运行失败的测试用例

        随着项目开发的进行,单元测试的数量也会成倍的增加。有时仅仅有数量很小的某几个测试用例会运行失败。在这种情况之下,对于每一次修改,可能并不需要跑完所有的测试用例。只需要重新运行前次运行失败的测试用例。TestNG 内建了重新运行上次失败测试用例的功能,下文将会给出重新运行前次错误测试用例的步骤。

        运行一组测试用例,如果这一组测试用例中有失败的用例,TestNG 就会在输出目录中创建一个叫做 testng-failed.xml 的配置文件。这个文件记录了本组测试用例中运行失败的测试用例。使用该文件,用户可以快速的重新运行上次运行失败的测试用例。而无需运行整个测试用例组。如前文所述,运行完 Ant 脚本之后,会在脚本运行的目录之中生成一个 test-output 目录。该目录中,包含 testng-failed.xml 文件。可以用如下的命令运行被标记为运行失败的测试用例。
列表 3. 重新运行前次运行失败的测试用例
    
C:\>java -classpath c:/spark/eclipse/plugins/org.testng.eclipse_4.7.0.0/lib/testng-jdk15.jar
 org.testng.TestNG -d test-outputs test-output\testng-failures.xml
 
运行结果如下:

                 图 4. 重新运行前次运行失败的测试用例的输出结果

                        
分布式测试特性

        随着测试用例规模的扩大,分组数量的增加。使用一台主机来运行所有的测试用例需要消耗大量的时间。为了解决这个问题,TestNG 提供了分布式特性。本文将介绍使用TestNG 分布特征——使用多台主机同时运行测试用例。TestNG 提供的分布式模型如下所示:
                                                        图 5. TestNG 提供的分布式模型

                            
        这是一个典型的 master/slave。在这个模型中,有一个负责调度的 master 节点,和一些负责执行任务的 slave 节点。下文将介绍如何配置这样一个分布式模型。

        首先,在远程机器上部署 slave 节点。如上图所示,在远程节点上不仅要配置 TestNG 运行环境,还需要复制测试用例文件。


                                               图 6. 将需要运行的测试用例部署到远程机器上

                            
        然后在这台远程机器上以 “slave” 模式启动一个 TestNG 实例,使用如下命令:java –classpath <testng_path>;<testcase_path> org.testng.TestNG -slave <port>
                                               图 7. 以“slave”模式启动一个 TestNG 实例

                          
        这样,一个 TestNG 实例将会被启动,并且等待即将到来的连接请求。如果有需要,可以在多台机器上以 slave 模式启动 TestNG 实例。

        完成了所有 slave 实例的启动之后,将所有启动 slave 实例的主机信息记录在一个配置文件中,如图 8 所示:


                                    图 8. 分布式运行的配置文件

                       
        然后使用该配置文件启动 TestNG 的 master 实例。

列表 4. 启动 TestNG 的 master 实例
    
java –classpath  c:\spark\eclipse\plugins\org.testng.eclipse_4.7.0.0\lib\testng-jdk15.jar;.
org.testng.TestNG -hostfile hosts.properties test-output\testng-failed.xml
 这样,所有的测试用例,将会被随机的分配到多个 slave 实例上运行。图9给出了在一个 slave 节点上运行测试用例的结果。

                                            图 9. 分布式运行的 TestNG 测试用例结果

                       
TestNG 的多线程支持

        测试用例分组中,针对网络应用的测试用例往往需要在多线程环境下运行。TestNG 为多线程运行某个测试用例提供了方便的内建支持。这可以通过在测试用例的方法前制定 annotation @Test 的属性来完成。

列表 5. 设置多线程属性运行测试用例
    
@Test(threadPoolSize = 3, invocationCount = 5,  timeOut = 1000, groups = { "multiple" })
public void multipleTest() {
    System.out.println("Slow test");
}

        这个属性表示,运行 multipleTest 方法总共 5 次,在 3 个线程中运行这五次调用。每个线程运行该方法的时间不超过 1000 毫秒。修改 build.xml 文件,运行 multiple 组。

列表 6. 修改 build.xml 文件,运行 multiple 组。
    
<target name="test">
  <testng classpathref="cp" groups="multiple">
    <classfileset dir="./" includes="example1/*.class"/>
  </testng>
</target>
                                       图 10. 多线程运行测试用例 multipleTest 的结果

                          
        本文希望通过场景和 TestNG 新特性的结合,可以为用户管理规模庞大的测试用例集有所帮助。场景中提到的分类方法,对实际项目中测试用例的管理具有帮助意义。其中,重跑失败的测试用例,分组运行,分布式运行,和多线程运行也是对于管理测试用例非常有帮助的特征。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值