| 网站首页 | 测试咨讯 | 新手入门 | 专注性能 | 测试技术 | 测试管理 | 测试工具 | 开发社区 | 工具下载 | 资料下载 | 测试论坛 | 

[CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523

新手入门
 入门指南
 经验之谈
测试咨讯
 行业新闻
 网站动态
 人才就业
 CNTester基金
 标准规范
专注性能
 性能测试知识
 性能测试工具
 程序设计性能
 数据库性能
 Web应用服务器性能
 操作系统性能
 服务器与网络性能
测试技术
 用例设计
 性能测试
 自动化测试
 Web测试
 面向对象测试
 综合技术
 阶段性测试
 行业类测试
测试管理
 项目管理
 项目案例
 质量管理
 软件过程
测试工具
 Mercury系列
 Rational系列
 测试管理工具
 性能测试工具
 功能测试工具
 单元测试工具
 其它测试工具
开发社区
 Java技术
 DotNet技术
 C技术
 数据库技术
 操作系统
 服务器与中间件
工具下载
 测试工具
 开发工具
 企业工程
 网络通信
 媒体桌面
 游戏娱乐
 其他工具
资料下载
 测试资料
 程序设计
 数据库
 操作系统
 应用服务器
 电子期刊
 其他资料
 
 
您现在的位置: 中国测试员网站 >> 测试工具 >> 单元测试工具 >> TestNG >> 文章正文
  [推荐]Eclipse 3.1 中使用TestNG:基于注释的单元测试框架         ★★★ 【字体:
Eclipse 3.1 中使用TestNG:基于注释的单元测试框架
作者:嫣 吴    文章来源:IBM    点击数:    更新时间:2007-5-17    

级别: 初级

嫣 吴 (wuyan@cn.ibm.com)IBM

2005 年 8 月 01 日

这篇文章将为大家介绍TestNG这个新的测试框架的特性,以及TestNG优于Junit3.X的地方。

TestNG(Test Next Generation),顾名思义,下一代的测试框架。它是基于J2SE5.0的注释特性的而构建的轻量级的单元测试框架结构。说起单元测试框架,大家都会自然地联想到JUnit。用过JUnit3.X的程序开发人员,都会发现JUnit在提供了强大功能的同时,也存在很多令人沮丧的地方。其中一个问题就是,JUnit3.x 在每个测试方法调用前和调用后都会调用setUp()和tearDown()的方法。如果开发人员希望在不同的测试方法中重用同一个JDBC连接或者JNDI的Context的时候,会觉得很不方便。一般的解决这个问题的方法是使用静态方法,而这样的话,就必须小心并发控制的问题(多个线程访问共享的静态对象)。除此之外,JUnit 3.X对于多线程测试也比较麻烦,需要其他模块的支持。

这篇文章将为大家介绍TestNG这个新的测试框架的特性,以及TestNG优于Junit3.X的地方。众所周知,Eclipse不仅仅是功能强大的Java IDE,同时也是一个开放的应用集成平台。而Eclipse3.1提供了对J2SE5.0的支持。因此,笔者将以Eclipse为运行环境,介绍Testng的安装,使用和运行。Eclipse3.1可以从http://www.eclipse.org/downloads/index.php下载。

关于注释

由于TestNG是基于J2SE5.0的注释特性所构建的。因此读者在阅读本文之前,必须了解注释的一些基本概念。关于J2SE的注释特性,笔者曾经在另一篇文章中详细的介绍过,详细介绍请参考"参考资料"。这里只简单的介绍一些概念。

注释是J2SE5.0所新提供的对于元数据的支持。程序开发人员可以在不改变原有逻辑的情况下,在源文件嵌入一些补充的信息。注释都是由@Interface annotationName 来声明的。注释可以用来修饰类定义,方法,域变量等等。使用的时候是在修饰的对象的定义前@annotationName。注释可以包含多个属性,使用的时候为属性赋值,例如 @annotationName(prop1=value1,prop2=value2)。程序的开发人员还可以通过Java的反射特性,在运行时获得这些注释的信息。在后面的章节中,大家会看到TestNG是如何使用它所定义的注释类型的来实现测试框架的。

安装TestNG

在Eclipse中安装testNG很简单。和安装其他的plugin的方法相似。首先启动Eclipse3.1,在Help->Software Update->Find and Install, 在弹出的向导中,选择"Search New Features to Install", 点击"New Remote Site",如图1所示。在URL中输入 http://beust.com/eclipse,点击"OK"。如图2所示,点击"Finish",Eclipse会帮助你完成下面的安装。熟悉Eclipse的读者对这个过程一定不会觉得陌生。



图1 新建Update Site
图1 新建Update Site


图2 安装TestNG
图2 安装TestNG

安装好TestNG后,在Eclipse中单击"Window"->Show View->Other->Java->TestNG, TestNG的视图就打开了。



图3 TestNG的视图
图3 TestNG的视图

注意:TestNG的视图的作用时为了现实测试结果。为了显示视图的功能,图3的视图是运行了一个测试用例后的结果。读者如果是第一次打开视图,应该是空白的。

一个简单的例子

TestNG和JUnit不同,他使用注释、正则表达式和基于XML的配置文件对测试方法进行配置的。我们先来看一个简单的例子。

1) 在Eclipse中创建一个Java的项目,com.catherine.lab.testng.demo

2) 在Packet Explorer中,右键点击刚生成的项目,选择Properties。

3) 在Properties属性框中,选择"Java Build Path",点击"Add External JARs…"

4) 在文件浏览的对话框中,选择{eclipse 3.1 home directory}/plugins/com.beust.testng.eclipse_XXX/eclipse_testng.jar,以及 {eclipse 3.1 home directory}/plugins/com.beust.testng.eclipse_XXX/lib/testng-jdk14.jar/以及testng-jdk15.jar. 点击OK

5) 在Project中创建一个package: com.catherine.lab.testng.firstTest。在package里边创建一个类:FristTestSample.



清单1 TestNG的第一个例子
package com.catherine.lab.testng.firstTest;
import com.beust.testng.annotations.*;
public class FirstTestSample {
	public FirstTestSample() {
		super();
	}
    @Test
    public void testPass() {
    		assert true :  "This test should pass.";
    }
    
    @Test
    public void testFail() {
    		assert false : "This test will fail";
    }	
    
    @Configuration(beforeTestClass = true)
	public void doBeforeTests() {
		System.out.println("invoke before test class!");
	}
    @Configuration(afterTestClass = true)
	public void doAfterTests() {
		System.out.println("invoke after test class!");
	}
}

6) 在Eclipse中打开Run->Run..,如图4所示。 首先在选择使用TestNG的Project,而后在选择编写了测试逻辑的Class,点击Run。测试结果就显示在TestNG的视图中了。如图5所示。



图4 配置运行TestNG的程序
图4 配置运行TestNG的程序


图5 TestNG的运行结果
图5 TestNG的运行结果

这是一个完整的测试用例。和JUnit不同,TestNG中实现测试逻辑的类不需要继承任何父类。测试方法也无需遵循testXXX的命名规则。

TestNG的类是大家所非常熟悉的普通的Java类,而在这个类中,所有的被@Test这个注释所修饰的方法都会被当作测试方法来运行。除了测试类之外,TestNG还需要了一个配置文件,用来配置测试过程。以下是一个简单的配置文件:testng.xml。



清单2 testNG的配置文件
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
 <suite name="My First TestNG test">
   <test name="Hello Test!">
    <classes>
      <class name=" com.catherine.lab.testng.firstTest.FirstTestSample " />
    </classes>
  </test>
</suite>

testng.xml可以配置测试套件<suite>,类似于JUnit的TestSuite。而<test>类似于JUnit中的TestCase。所不同的是, TestNG中的测试套件可以包括多个测试用例,一个测试用例可以包括多个测试类,而一个测试类中可以定义多个测试方法。在下面的例子中,我们将看到这个配置文件更复杂的应用。

在图4的运行配置中,我们也可以设置一个xml文件作为配置文件,而不是直接使用测试类。其实我们使用测试类的时候,testNG也帮我们生成了一个缺省的xml文件。不相信的话,你可以切换到Resource Perspective,然后刷新Workspace,就会发现这个project里边生成了一个xml文件,而这个文件就是TestNG的缺省的配置文件。

现在我们再回到清单1,大家在上面的程序清单中会发现,除了使用@Test这个注释以外,我们还使用了@Configuration这个注释。下面我们就来介绍@Configuration这个注释的用途。

在注释Configuration中,定义了以下的属性:



清单3 configuration中的属性
public boolean beforeSuite() default false;
public boolean afterSuite() default false;
public boolean beforeTest() default false;
public boolean afterTest() default false;
public boolean beforeTestClass() default false;
public boolean afterTestClass() default false;
public boolean beforeTestMethod() default false;
public boolean afterTestMethod() default false;

  • beforeSuite=true,所修饰的方法将在测试套件(也就是配置文件中的Suite Tag)中任何一个方法调用之前,调用一次
  • afterSuite=true,所修饰的方法将在测试套件中所有方法都调用过后,调用一次
  • beforeTest=true,在测试用例(配置文件中Test Tag)中任何一个测试方法调用之前,调用一次
  • afterTest=true, 在测试用例中任何所有方法都调用之后,调用一次
  • beforeTestClass=true,在测试类中任何测试方法调用之前,调用一次
  • afterTestClass=true,在这个测试类中所有方法都调用过后,调用一次
  • beforeTestMethod=true,在每个测试方法调用之前,调用一次
  • afterTestMethod=true,在每个测试方法调用之后,调用一次

这个清单1中doBeforeTests()方法,在任何一个test方法调用之前被调用一次。doAfterTests,就是所有的test方法运行过了以后再调用一次。从Console输出的信息中,我们可以验证这一点:



图6 console输出的运行信息
 图6 console输出的运行信息 

更复杂的例子

上一节中我们介绍了使用testNG的一个最简单的例子,这一节中我们将介绍一些关于testNG的高级应用。注释Test除了标志其修饰的方法为测试方法, 还提供了groups的属性。比如上面例子的两个方法testPass()和testFail(),我们可以给这两个方法加上group的属性。



清单4 测试@Test的groups属性
     @Test(groups={"functional_test"})
    public void testPass() {
    		assert true :  "This test should pass.";
    }
        @Test(groups={"checkin_test"})
    public void testFail() {
    		assert false : "This test will fail";
    }	
   }
   

而后打开Run->Run…,在配置文件的Runtime配置中选择Groups,然后选择你要运行的group的名字。



图7 运行选定的测试组
图7 运行选定的测试组

这个时候我们从TestNG中看到测试结果,只有testPass运行了,而testFail因为不属于funcational_test这个组,因此并没有运行。



图8 运行结果
图8 运行结果

和第一个例子类似,虽然我们在这里并没有显示地定义配置文件,testNG已经生成了相应的配置文件了。在Resource Perspective底下可以看到这个文件:Custom_SuiteXXXX.xml.



清单5 自动生成的配置文件
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
 <suite name="My First TestNG test">
   <test name="Hello Test!">
<groups>
    <run>
      <include name="functional_test"/>
     </run>
  </groups>
    <classes>
      <class name=" com.catherine.lab.testng.firstTest.FirstTestSample " />
    </classes>
  </test>
</suite>

除了groups属性以外,注释Test还支持属性dependsOnMethods和属性dependsOnGroups. 这两个属性主要用于规定测试方法的执行顺序。

TestNG并不保证按照定义的顺序执行测试方法。如果这些测试方法之间有依赖关系的话,那么我们就可以使用dependsOnXXXX的属性。我们还是看第一个例子,现在我们在这个例子里边增加了一个方法:

setupEnvforPass()。我们希望setupEnvforPass()方法在testPass方法前执行,我们修改了testPass的test注释。如清单6所示:



清单6 测试@Test的属性dependsOnMethods
    @Test(groups={"functional_test"},
dependsOnMethods = { "setEnvForPass" })
    public void testPass() {
    		assert true :  "This test should pass.";
    }
        @Test(groups={"checkin_test"})
    public void testFail() {
    		assert false : "This test will fail";
}	
@Test(groups = {"init"})
public void setEnvForPass(){
   assert true: "This is dependent method"
}
   }
  

运行配置和配置文件都不需要改动,现在我们来运行这个例子,测试结果如图9所示。大家可以看到,虽然我们在testPass方法之后定义了,setEnvForPass方法,但是由于我们将setEnvForPass定义为testPass的以来方法,setEnvForPass在testPass前执行了。

同样,我们可以定义dependsOnGroups的属性,这样只有Groups中所有的方法都被执行完,这个方法才会被执行。注意:如果depensOnGroups中制定的group在配置文件中被excluded了,那么这个方法会依然被执行。但是如果指定的group在配置文件中被include了,而group中的方法有错误的话,那么这个方法会被skip,不会被执行。



图9 运行结果
图9 运行结果

下面我们要介绍一个新的注释类型: @Parameter。

TestNG的测试方法可以带有参数,参数可以通过@Parameter来声明,具体的参数值在testng.xml中定义。这是testng的一个很优越的特性。我们还是在以前的例子上的基础上来验证这个特性。我们为setEnvForPass这个方法定义一个参数,target_server,并且在测试方法中打印这个参数。



清单7 测试注释Parameter
@Parameters({ "target_server" })
@Test(groups = {"init"})
public void setEnvForPass(String targetServer){
   assert true: "This is dependent method";
System.out.println(targetServer);
}
   }

Target_server的值在testng.xml中定义。在TestNG的运行时配置中选择Suite,然后Browse清单8中定义好的的testng.xml。运行TestNG,我们从Console的运行结果中看到,target_server的值被打印出来了。



清单8 自定义的配置文件
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd">
<suite name="Custom suite">
  <parameter name="target_server"  value="127.0.0.1"/>
  <test verbose="6" name="Test for 1 classes" annotations="1.5">
    <groups>
      <run>
        <include name="functional_test"/>
      </run>
    </groups>
    <classes>
      <class name="com.catherine.lab.testng.firstTest.FirstTestSample">
      </class>
    </classes>
  </test>
</suite>

测试方法的参数可以是任意多个,只要你通过配置文件传入了正确的参数,那么测试方法中就可以使用这些参数了。不过需要注意的是,参数是有作用域的,比如参数可以在配置文件的suite和test之后定义,而如果两个参数的名称一样,test中定义的参数值有较高的优先级。

testNG可以从多个线程中运行测试方法,只需要将配置文件中suite的parallel属性设为true。线程的数目在thread-count中设置。如果两个方法有依赖关系,那么他们将在一个线程中运行,除此之外,都可以在多个线程中并发的运行。

<suite name="My suite" parallel="true" thread-count="10">

除了以上介绍的特性以外,(请参阅"参考资料")

  • TestNG提供了注释Factory,用来动态生成测试方法的参数。
  • TestNG还提供了AntTask <testng>,可以从Ant脚本中调用testNG。
  • TestNG的可以调用JUnit的test cases。只需要配置文件中声明
    <test name="Test1" junit="true">
    <classes ..>
  • TestNG还可以从程序中调用:
    TestNG testng = new TestNG();
    testng.setTestClasses(Class[] {});
    testng.run();

除了TestNG之外… 从上面的例子可以看出,TestNG这个单元测试框架的功能是很强大的,而且简单易学。开发者只需要使用TestNG所提供的注释和正确的配置文件,可以轻松地完成复杂的测试用例。

除了TestNG之外,JTiger也是一种基于J2SE5.0的单元测试框架,其中应用了大量J2SE5.0的新特性,比如注释和静态Import。和TestNG类似, JTiger提供了大量内建的注释类型, 比如JTiger也使用注释@Test标明测试方法, 使用注释@Category表示这个测试方法属于那一类,类似于TestNG的@Test的groups属性。和TestNG不同的是,JTiger并没有使外部的配置文件。

总之,TestNG和JTiger都解决了JUnit3.x中存在的问题,提供了大量优于JUnit3.x的特性。而JUnit也并没有就此止步,即将发布的JUnit4.0有了根本性的变化,JUnit4.0也将变成基于注释的测试系统。同样也将提供大量的内建注释类型:比如@Test, @Before, @After等等。这些引入的注释类型,使得JUnit克服了以前的问题,拥有了新的活力。Justine Lee在他的文章中,详细地比较了这三种测试框架,请参阅"参考资料"。

选用何种测试框架,取决于很多的因素。虽然JUnit具有众多的拥簇者,但是TestNG和JTiger的崛起也不可小觑的。应该说,TestNG是建立在JUnit3.x之上的,吸取了JUnit的优点,同时也摈弃和改正了JUnit的缺点。笔者曾经在Eclipse中使用过JUnit3.x和TestNG,个人认为TestNG使用起来比JUnit3.x要更为方便。但是JUnit提供测试插件(plug-in)的功能,TestNG目前并没有提供这种功能。不过我们有理由相信,在不久的将来TestNG会对于eclipse插件提供更为丰富的支持。本文通过对TestNG的介绍,希望能够为大家在选择测试框架的时候提供一个新的选择。

文章录入:root    责任编辑:root 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
    最新热点 最新推荐 相关文章
    · 常用软件测试工具简介!
    · Test Director 8.0安装配置!
    · Parasoft Jtest 7.5.59 使用手册
    · Test Director 8.0项目数据库维护和移植!
    · 使用CQ TestManager 运行并分析软件测试
    · TestDirector 8.2 SP2的下载与安装
    · Mercury WinRunner 软件试用 下载
    · Winrunner TSL命令简介
    · Mercury TestDirector 软件试用 下载
    · JTest7.59定义——JAVA 编码标准规范
    · 初识IBM Rational RobotJ
    · 使用 Rational Robot 实现自动化测试
    · 使用CQ TestManager 运行并分析软件测试
    · 常用软件测试工具简介!
    · 使用Functional Tester 6.1 进行功能测试
    · 使用Functional Tester 6.1 进行功能测试
    · 使用Functional Tester 6.1 进行功能测试
    · 使用Functional Tester 6.1 进行功能测试
    · 使用 EclEmma 进行覆盖测试
    · JTest7.59定义——JAVA 编码标准规范
    测试分类技术与Testng
    TestNG 使 Java 单元测试轻而
    使用 TestNG 的新特性管理实
    追求代码质量: 使用 TestNG-
     
     
     
    ======> [CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | 

    Copyright@2007 by CNTester.com 中国测试员网站 桂ICP备07005590

    本站为开源免费网站,非商业赢利性组织。本站文章部分从网络搜索获取,如果您认为某些侵犯了您的权益,麻烦您联系本站,我们会尽快删除相关内容,同时也希望您的谅解,我们的初衷是为了让更多人去学习这方面的知识,让行业有更好的发展。

    联系电话: 15021358905