单元测试框架TestNg使用总结

摘要:
工欲善其事,必先利其器单元测试的重要性是不言而喻的。Testng便是利器之一。下面我将总结一些TestNg的重要特性。关于testng.xmlTestng.xml是以xml记录所有测试的文件。它描述了测试套件的运行时定义,也是testng中运行测试的最大工作单元。使用依赖时需要注意的是要避免循环依赖测试分组Testing当中提供的组名,与java当中包的概念有些类似,都是将包含相似点的类归为一组。

工欲善其事,必先利其器

单元测试的重要性是不言而喻的。但如果没有好的单元测试工具,是无法激起开发人员的欲望。

Testng便是利器之一。TestNG是基于Annotation的测试框架的先驱,他拥有通过添加诸如灵活的装置、测试分类、参数测试和依赖方法等特性来克服JUnit3的一些不足之处。下面我将总结一些TestNg的重要特性。

关于testng.xml

Testng.xml是以xml记录所有测试的文件。它描述了测试套件的运行时定义,也是testng中运行测试的最大工作单元。虽然没有testng.xml文件,测试也很容易被执行。但是随着测试代码的增长,testng.xml提供了方便用来存放所有运行时的配置,如设置有关类,测试,方法,参数,分组的包含与排除等。在测试类越来越多时,它就显得非常重要。

Testing.xml的主要结构

根标签是<suite>

<suite>标签包含一个或多个<test>标签

<test>标签包含一个或多个<classes>标签

<classes>标签包含一个或多个<method>标签

一般来说,大多数文件详细到<classes>标签即可。

Testing.xml的额外标签

<packages>和<package>:顾名思义,它们可以指定一组java包,在这个标签中还可以用包含<include>或者排除<exclude>属性。

<parameter>定义了参数名称和值,它的使用是与测试类当中@Parameters的注释结合使用的,作用和@Dataprovider类似,提供外部参数,功能不如@Dataprovider强大,有局限性。

<suite-files>和<suite-file>:它是用来引入其他testng.xml文件的,这些文件将于当前文件一起执行。

<groups>,<define>和<run>:这三个标签结合使用,在执行时用来指定或者排除一部分的分组,以一个例子见分晓:

Xml代码
  1. <groups>
  2. <definename=”all”>
  3. <includename=”test1”/>
  4. <excludename=”test2”/>
  5. </define>
  6. <run>
  7. <includename=”all”/>
  8. </run>
  9. <groups>

注意执行测试的默认顺序是按照testng.xml里给定的顺序执行的。如果你不希望按此顺序执行,请使用preserve-order属性指定为false。如<test name="Regression1" preserve-order="false">。关于testng.xml的标签详细说明,可参见testng.xml的官方文档。

在实际开发时,我建议testng.xml以功能点为粒度进行划分。然后以总的testng.xml将各个功能点的配置汇总起来。

参数传递

Testng改进了传统测试框架无法传递参数的缺点,它能够提供了想测试方法传递参数的最简单两种的方法:

1,在测试方法上加@Parameters标签,然后在testng.xml给出参数。

2,指定@Dataproviders。

第一种方式的缺点很明显,它只支持java基本类型,并且在构造值时,无法包含计算逻辑得到需要的参数。

第二种方式可以想测试方法传递任何有效的java类型。我们倾向于第二种方法来构造参数。

在此,我们再介绍一种传递参数的方式:工厂注释@Factory,它不同于前面两种参数传递。

让我们回顾一下普通的testng测试,这些测试类是无参数构造方法(默认构造方法,无法接受参数)的。@Factory的出现,正是弥补这一缺陷而产生的。@Factory的方法在执行时会被首先检查并执行,且只执行一次。执行完以后返回一个Object数组。这个数组里对象的内容便是当前测试方法带了构造函数的实例。在使用@Factory的同时,该测试类还有一个对应带参数的构造函数,@Factory就是为以构造函数提供参数的形式提供了帮助。

测试的依赖与分组

我们在将依赖与分组放在一起描述,是因为他们之间有着紧密的联系。

测试依赖

测试方法之间的依赖是一种很常见的需求,您也许认为,测试之间的依赖不是破坏了测试方法之间的隔离性吗?确实是这样的,但是有时为了这种隔离性,在彼此隔离的测试方法当中要付出很大的代价去相互模拟,所以为了方便起见,testng提供了这种依赖的方式。

Testng当中通过@Test的属性dependsOnMethods,dependsOnGroups来实现针对方法和分组的依赖。

依赖还包括软依赖和硬依赖。硬依赖是很强的关联,如果被依赖的测试失败,那么依赖它的测试会跳过。而软依赖则不会跳过。通过给@Test设定alwaysRun=true来实现软依赖。使用依赖时需要注意的是要避免循环依赖

测试分组

Testing当中提供的组名,与java当中包的概念有些类似,都是将包含相似点的类归为一组。

分组的最重要的目标就是:使固定的测试代码和执行哪些测试实现清晰的分离。当你需要指定执行哪些组的测试时,在动态执行时指定组即可。

关于分组的语法是非常简单的,@Test,@BeforeClass,@AfterClass,@BeforeMethod等都可以属于分组。相关的语法是@Test(groups=”group1”),一个@Test的groups还可以指定多个组名,如@Test(groups=”group1,groups2”)。

定义好的组名,其实是给运行时使用的,也就是在testng.xml文件当中可以配置。前面的testng.xml说明当中就提到了<groups>的用法。

Group的组织可以根据各种维度来进行划分,如单元测试,集成测试,性能测试。或者是框架分层来划分如action,service,dao等。在配置文件当中还可以定义组中组,通过define标签来实现,前面也有所说明。

在一般项目中,我建议组分类可按照架构分层来定义,分为基础功能,service业务以及dao层。

expectedExceptions

用expectedExceptions来测试异常有两个好处:其一,它消除了try/catch语句给代码带来的干扰。其二,使得测试代码表达的意图更加清楚。只要看到@Test注释当中定义的expectedExceptions属性,就知道该测试方法的意图,把Exception的用例和预期业务功能的用例分到不同测试方法中。

语法很简单,@Test(expectedExceptions=”XXXException.class”),异常类可以有多个,用逗号隔开。

异步与并发测试

异步与并发在单元测试当中通常都比较困难。

关于异步测试,如JMS,发送和接收是解耦的,如果是测试发送消息的方法,当收到响应时,会有返回值。根据这个场景,测试代码通常是这样:

Java代码
  1. PrivatevolatileBooleansuccess=”false”;
  2. @Test(groups=”send”)
  3. PublicvoidsendMessage(){
  4. //sendmessagecode
  5. }
  6. @Test(timeOut=10000,invocationCount=1000,successPercentage=98,dependsOnGroups={“send”})
  7. PublicvoidwaitForAnser(){
  8. While(!success){
  9. Thread.sleep(1000);
  10. }
  11. }

@Test(timeOut = 10000, invocationCount = 1000,successPercentage = 98),是用于测试系统的可用性和响应速度所设的值。这里告诉testng调用该方法1000次,如果98%的调用是成功的,就认为是通过测试。当然,前面也要调用sendMessage方法1000次。timeOut是防止死锁而产生的。

Testing内建了对并发的支持,可以分为两种

1,并发测试

Testng在做并发测试时提供了threadPoolSize,invocationCount和timeOut三个属性来完成。threadPoolSize可以指定多个线程池来执行测试方法。

2,并发执行测试

Testing还可以通过testng.xml来设置并发执行。testng.xml默认是单线程执行的。

<suite>标签可以设置parallel属性。Thread-count指定线程数

parallel=”methods”:每个测试方法都在它自己的线程中执行(以方法为粒度)。

parallel=”tests”:在某个<test>标签内的所有测试方法都在它自己的线程中执行(以<test>为粒度)。

免责声明:文章转载自《单元测试框架TestNg使用总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ubuntu SVN 搭建谈C/C++ 指针精髓 CHRIS下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【XStream】xml和java实体的相互转化

1.pom.xml <!-- xstream xml和Java对象转化 --> <dependency> <groupId>xstream</groupId> <artifactId>xstream</artifactId...

oracle sqlplus 命令行中创建存储过程

while 循环插入测试数据 1.创建存储过程 create or replace procedure proc_test_while is i number; begin i := 0; while i < 40 loop i := i + 1; insert...

shell用法总结

shell基础的一些东西   ●umask   --查看当前用户创建文件或文件夹时的默认权限  [test@szbirdora 1]$umask 0002 [test@szbirdora 1]$ls -lh -rw-rw-r-- test test myfile drwxrwxr-x test test 1 上面的例子中我们...

nodejs--Nodejs单元测试小结

前言 最近在写一课程的Project,用Node写了一个实时聊天小应用,其中就用到了单元测试。在写Node单元测试的时候,一方面感受到了单元测试的重要性,另一方面感受到了Node单元测试的不够成熟,尚未有成熟的理论体系,所以想写篇博客探讨一下Node里面单元测试的方法。示例代码部署在Github上面,地址是:https://github.com/blogd...

使用jest进行单元测试

以前,写完一段代码我也是直接调用或者实例化一下,发现过了就把测试相关部分删了。今年的不幸与坎坷使我有很长一段时间去思考人生,不想将就了,鲁棒健壮的程序,开发和测试应该是分得很开的,于是我选择jest去做单元测试这件事。 为什么要做单元测试 在开始之前,我们先思考这样一个问题,我们为什么要做单元测试? 不扯犊子直接说吧,第一点,用数据、用茫茫多的测试用例去告...

Ajax请求中,contentType和dataType的区别

contentType: (默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数情况。如果你明确地传递了一个content-type给 $.ajax() 那么他必定会发送给服务器(即使没有数据要发送). 其他可选的类型有:form-data x-www-form-orlencod...