工欲善其事,必先利其器
单元测试的重要性是不言而喻的。但如果没有好的单元测试工具,是无法激起开发人员的欲望。
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>:这三个标签结合使用,在执行时用来指定或者排除一部分的分组,以一个例子见分晓:
<groups>
<define name=”all”>
<include name=”test1”/>
<exclude name=”test2”/>
</define>
<run>
<include name=”all”/>
</run>
<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,发送和接收是解耦的,如果是测试发送消息的方法,当收到响应时,会有返回值。根据这个场景,测试代码通常是这样:
Private volatile Boolean success=”false”;
@Test(groups=”send”)
Public void sendMessage(){
//send message code
}
@Test(timeOut=10000,invocationCount=1000,successPercentage=98,dependsOnGroups={“send”})
Public void waitForAnser(){
While(!success){
Thread.sleep(1000);
}
}
@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进行单元测试和集成测试。 1. **TestNG基本概念** TestNG允许测试用例以注解的方式定义,如`@Test`,`@BeforeMethod`,`@AfterMethod`等。这些注解简化了测试代码的编写,并提供...
### TestNG单元测试学习总结 #### 一、TestNG框架简介 **1.1 概念** TestNG(Test Next Generation)是一个高级测试框架,它继承了JUnit与NUnit的优点,并在此基础上添加了许多新的功能。TestNG是一个开源的、...
总结来说,文档提供的内容涵盖了从环境搭建到测试执行的各个方面,为开发者提供了一套完整的Spring集成TestNG和Mockito框架的单元测试指南。通过遵循文档中的步骤和规范,开发者可以快速掌握如何为自己的Spring项目...
**JUnit** 是 Java 社区中最早的单元测试框架之一,它的设计初衷是为了解决单元测试的问题。随着时间的发展,JUnit 虽然被广泛应用于各种类型的测试,但也暴露了一些局限性: - **依赖性测试支持不足**:JUnit 不...
这里提及的框架可能包含了如JUnit、TestNG等单元测试框架,以及RestAssured、Postman或WireMock等工具用于接口测试。 其次,WEB UI自动化测试关注于Web应用程序的用户界面。这类测试通常使用Selenium WebDriver等...
1. **JUnit**:最常用的Java单元测试框架之一,提供了丰富的API来定义测试用例、断言等。JUnit4和JUnit5是两个重要的版本,其中JUnit5相比JUnit4有了很大的改进,包括更好的模块化支持和更简洁的语法。 2. **TestNG*...
JUnit是Java编程语言中的一个单元测试框架,被广泛用于Android应用的单元测试。它允许开发者编写可重复执行的测试用例,确保代码模块的功能正确性。Espresso则是一个用于UI测试的库,它提供了直观、简洁的API来编写...
**TestNG**(Next Generation Testing)是一个强大的测试框架,旨在满足各种测试需求,从单元测试到集成测试,甚至更复杂的系统测试场景。它的一个核心优势在于不仅支持传统的单元测试,还能很好地应用于集成测试...
TestNG是由Cédric Beust创建的一个开源测试框架,旨在简化单元测试和集成测试。相比于JUnit,TestNG提供了更多的特性,比如支持多种测试类型(如方法、类、接口和配置方法)、支持数据驱动测试、XML配置文件定义...
TestNG由Cédric Beust创建,它的设计目标是提供一种灵活、可扩展的测试解决方案,支持多种测试类型,包括单元测试、集成测试、功能测试等。相比JUnit,TestNG引入了并行测试、配置方法、数据驱动测试、依赖性管理等...
- **JUnit**:流行的Java单元测试框架,提供了丰富的断言和测试注解。 - **Mockito**:强大的模拟库,用于创建桩对象和验证方法调用。 - **PowerMock**:扩展了Mockito的功能,可以模拟静态方法、构造函数等难以模拟...
JUnit5是Java领域广泛使用的单元测试框架。它引入了新的注解、测试生命周期管理和扩展机制,简化了测试代码的编写。在JUnit5中,测试用例的编写通常包含以下步骤: 1. 引入JUnit5库依赖。 2. 使用`@Test`注解标记...
TestNG是一款强大的测试框架,专为Java开发人员设计,提供了丰富的功能来支持单元测试、集成测试以及端到端测试。它的出现是对JUnit的一种扩展,增加了许多高级特性,如并发测试、参数化测试、依赖管理以及更详细的...
总结一下,JUnit4是一个强大的单元测试框架,它的注解驱动使得测试代码更简洁,断言机制便于检查代码行为,参数化测试、异常测试、分类和分组等功能则提高了测试的灵活性和覆盖率。通过合理使用JUnit4,开发者能够...
TestNG则是一个功能强大的测试框架,支持多种测试类型,如单元测试、集成测试和功能测试,同时提供了灵活的测试配置和丰富的异常处理机制。 ExtendReport是TestNG的一种第三方报告插件,它扩展了TestNG的默认报告,...
私有方法通常不直接暴露给外部调用,因此,常规的单元测试框架如JUnit或TestNG可能无法直接对它们进行测试。然而,这并不意味着我们不能或者不应该测试这些方法。实际上,有几种策略可以用来确保私有方法的正确性。 ...
TestNG是一款强大的测试框架,特别适合于进行单元测试、集成测试和功能测试。本手册将指导你如何在MyEclipse环境中配置和使用TestNG进行Java工程的测试。 **环境准备** 1. **安装MyEclipse**:MyEclipse是基于...
单元测试通常使用专门的测试框架,如JUnit(Java)或pytest(Python)。在这个场景中,我们可能需要为Java代码编写JUnit测试用例,因为Resin是一个Java应用服务器。 IntelliJ IDEA是一个强大的Java IDE,内置了对...
你可以使用JUnit或TestNG作为基础测试框架,结合Spring TestContext Framework来创建和管理测试上下文,以便于隔离和测试单个组件或服务。 接下来,Struts测试主要关注基于Struts框架的应用程序。Struts是一个MVC...