TestNG,即Testing, Next Generation,下一代测试技术,是一套根据JUnit 和NUnit思想而构建的利用注释来强化测试功能的一个测试框架。TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use。java
@BeforeSuite: 被此注解的方法将在全部测试运行以前运行该方法。mysql
@AfterSuite: 被此注解的方法将在全部测试运行以后运行该方法。linux
@BeforeTest: 被此注解的方法,将在测试类运行以前运行,只被执行一次。正则表达式
@AfterTest: 被此注解的方法,将在测试运行以后运行。sql
@BeforeClass: 被此注解的方法,将在当前类的第一个测试方法调用以前运行windows
@AfterClass: 被此注解的方法,将在当前类的全部测试方法调用以后运行安全
@BeforeMethod: 被此注解的方法,将在每一个测试方法调用以前运行多线程
@AfterMethod: 被此注解的方法,将在每一个测试方法调用以后运行。并发
@Test: 将类或方法标记为测试的一部分,此标记若放在类上,则该类全部公共方法都将被做为测试方法框架
@DataProvider: 标记一种方法来提供测试方法的数据。 注释方法必须返回一个Object [] [],其中每一个Object []能够被分配给测试方法的参数列表。 要从该DataProvider接收数据的@Test方法须要使用与此注释名称相等的dataProvider名称
@Parameters: 描述如何将参数传递给@Test方法
@Factory: 将一个方法标记为工厂,返回TestNG将被用做测试类的对象。 该方法必须返回Object []
@Listeners: 定义测试类上的侦听器
断言类是Assert.java,里面有多个静态方法被称为硬断言,硬断言就是,若是运行到折行断言失败,即便后面还有其余代码行,也不会继续执行下去。
(1) assertTrue:判断是否为True。
(2) assertFalse:判断是否为false。
(3) assertSame:判断引用地址是否相同。
(4) assertNotSame:判断引用地址是否不相同。
(5) assertNull:判断是否为null。
(6) assertNotNull:判断是否不为null。
(7) assertEquals:判断是否相等,Object类型的对象须要实现haseCode及equals方法。
(8) assertNotEquals:判断是否不相等。
(9) assertEqualsNoOrder:判断忽略顺序是否相等
SoftAssert的特色
1) 若是一个断言失败,会继续执行这个断言下的其余语句或者断言
2) 也就是一个用例有多个断言,失败了其中一个,不影响其余断言的运行
3) 不要忘记调用assertAll()在该用例的最后一个断言后面
4) 软断言的类,叫SoftAssert.java,这个类是须要建立实例对象,才能调用相关实例方法进行软断言
具体实例方法此处忽略,请参考硬断言方法。
预期异常测试经过在@Test注解后加入预期的Exception来进行添加,范例以下所示:
@Test(expectedExceptions = ArithmeticException.class)
public void divisionWithException() {
int i = 1 / 0;
System.out.println("After division the value of i is :"+ i);
}
测试其余异常同样的,只须要在@Test注解后加入预期的Exception便可,假如出现了该异常,则会判断测试经过。
有时候咱们写的用例没准备好,或者该次测试不想运行此用例,那么删掉显然不明智,那么就能够经过注解@Test(enabled = false)
来将其忽略掉,此用例就不会运行了,默认是true。
“超时”表示若是单元测试花费的时间超过指定的毫秒数,那么TestNG将会停止它并将其标记为失败。此项经常使用于性能测试。以下为一个范例:
@Test(timeOut = 3000) // time in mulliseconds
public void testThisShouldPass() throws InterruptedException {
Thread.sleep(4000);
}
分组测试即为使用group,若是你使用xml的话就是里边的<groups>标签,若是是直接在class中,是经过@Test(groups="group2")这种方式来分组,并且@BeforeGroup是须要添加group名称才能够正确挂载到该group下的;
这个group说明能够是在单个的测试方法上,也能够在class上,只要具备一样的group名称都会在同一个group中,同时group名称能够有多个,相似@Test(groups = {"mysql","database"})这种
xml文件配置以下:
<suite name="Suite" parallel="false">
<test name="Test">
<groups>
<incloud name="group1"></incloud>
<incloud name="group2"></incloud>
</groups>
<classes>
<class name="com.demo.test.testng.NewTest"/>
<class name="com.demo.test.testng.TestCase1"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
测试套件是用于测试软件程序的行为或一组行为的测试用例的集合。 在TestNG中,咱们没法在测试源代码中定义一个套件,但它能够由一个XML文件表示,由于套件是执行的功能。 它还容许灵活配置要运行的测试。 套件能够包含一个或多个测试,并由<suite>标记定义。<suite>是testng.xml的根标记。 它描述了一个测试套件,它又由几个<test>部分组成。
下表列出了<suite>接受的全部定义的合法属性。
属性 描述
name 套件的名称,这是一个强制属性
verbose 运行的级别或详细程度,级别为0-10,其中10最详细
parallel TestNG是否运行不一样的线程来运行这个套件,默认为none,其余级别为methods、tests、classes、instances
thread-count 若是启用并行模式(忽略其余方式),则为使用的线程数
annotations 在测试中使用的注释类型
time-out 在本测试中的全部测试方法上使用的默认超时
有时,咱们可能须要以特定顺序调用测试用例中的方法,或者可能但愿在方法之间共享一些数据和状态。 TestNG支持这种依赖关系,由于它支持在测试方法之间显式依赖的声明。
TestNG容许指定依赖关系:
在@Test注释中使用属性dependsOnMethods
在@Test注释中使用属性dependsOnGroups
除此以外依赖还分为hard依赖和soft依赖:
hard依赖:默认为此依赖方式,即其全部依赖的methods或者groups必须所有pass,不然被标识依赖的类或者方法将会被略过,在报告中标识为skip,如后面的范例所示,此为默认的依赖方式;
soft依赖:此方式下,其依赖的方法或者组有不是所有pass也不会影响被标识依赖的类或者方法的运行,注意若是使用此方式,则依赖者和被依赖者之间必须不存在成功失败的因果关系,不然会致使用例失败。此方法在注解中须要加入alwaysRun=true便可,如@Test(dependsOnMethods= {"TestNgLearn1"}, alwaysRun=true);
在TestNG中,咱们使用dependOnMethods和dependsOnGroups来实现依赖测试。 且这两个都支持正则表达式,以下面所示:
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.*" })
public void method1() {}
TestNG中的另外一个有趣的功能是参数化测试。 在大多数状况下,您会遇到业务逻辑须要大量测试的场景。 参数化测试容许开发人员使用不一样的值一次又一次地运行相同的测试。
TestNG能够经过两种不一样的方式将参数直接传递给测试方法:
使用testng.xml
使用数据提供者
下面分别介绍两种传参方式:
范例代码以下:
public class TestCase1 {
@Parameters({"param1", "param2"})
public void TestNgLearn1(String param1, int param2) {
System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
Assert.assertFalse(false);
}
}
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
<test name="Test">
<parameter name="param1" value="1011111" />
<parameter name="param2" value="10" />
<classes>
<class name="com.demo.test.testng.TestCase1"/>
</classes>
</test>
</suite>
@DataProvider
传递参数此处须要注意,传参的类型必需要一致,且带有@DataProvider
注解的函数返回的必然是Object[][]
,此处须要注意。
示例代码以下:
public class TestCase1 {
@DataProvider(name = "provideNumbers")
public Object[][] provideData() {
return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
}
@Test(dataProvider = "provideNumbers")
public void TestNgLearn1(int param1, int param2) {
System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
Assert.assertFalse(false);
}
以下分别讲解各个标签:
testNG.xml文件的最外层标签即suite,即测试套件,其下能够有多个<test>和<groups>,其有几个能够添加的属性在第十节的分suite测试中有作说明,这里作下详细说明:
(1)、name属性
此属性属于必需要有的,值能够自行设定,此名字会在testNG的报告中看到;
(2)、verbose属性
此属性为指定testNG报告的详细程度,从0开始到10,其中10为最详细,默认生成的xml此属性值为1;
(3)、parallel属性
此属性是指代运行方式,默认为none,即串行运行方式;并行执行方法包括以下几种,下面作分别说明:
a.methods:方法层级,若为此值,则该suite下全部的测试方法都将进行多线程,即测试用例级别的多线程。若是用例之间有依赖,则执行顺序会按照设定的依赖来运行;
<suite name="My suite" parallel="methods" thread-count="5">
b.tests:TestNG将在同一线程中运行相同的<Test>标签中的全部方法,每一个<test>标签都将处于一个单独的线程中,这容许您将不是线程安全的全部类分组在同一个<test>中,并保证它们都将在同一个线程中运行,同时利用TestNG使用尽量多的线程运行测试。
<suite name="My suite" parallel="tests" thread-count="5">
c.classes:类级别并发,即TestNG会将该suite下每一个class都将在单独的线程中运行,同一个class下的全部用例都将在同一个线程中运行;
<suite name="My suite" parallel="classes" thread-count="5">
d.instances:实例级别,即TestNG将在同一线程中运行同一实例中的全部方法,两个不一样实例上的两个方法将在不一样的线程中运行。
<suite name="My suite" parallel="instances" thread-count="5">
(4)、thread-count属性
此属性用于指定线程数,按照须要输入,须要parallel参数非none时才能够添加;
(5)、annotations属性
此项为注解的级别,为methods级别和class级别,通常不用设置;
(6)、time-out属性
此属性用于指定超时时间,该suite下全部的用例的超时时间;
(7)、group-by-instances属性
此项用于那些有依赖的方法,且被依赖的对象有多个重载对象,由于若是是依赖方法,且该方法有多个重载方法,则默认是会将全部重载方法都跑完再运行被依赖方法,但有时候咱们不想这样,则将此项设置为true便可;
(8)、preserve-order属性
值可输入true或者false,若是为true,则用例执行会按照在xml中的顺序执行,不然会乱序执行,不添加此属性的话默认是按顺序执行的;
此标签无特别意义,其下能够包括多个标签,如groups、classes等,以下介绍下几种书写方式:
选择一个包中的所有测试脚本(包含子包)
<test name = "allTestsInAPackage" >
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
选择一个类中的所有测试脚本
<test name = "allTestsInAClass" >
<classes>
<class name="whole.path.to.package.className />
</classes>
</test>
选择一个类中的部分测试脚本
<test name = "aFewTestsFromAClass" >
<classes>
<class name="whole.path.to.package.className >
<methods>
<include name = "firstMethod" />
<include name = "secondMethod" />
<include name = "thirdMethod" />
</methods>
</class>
</classes>
</test>
选择一个包中的某些组
<test name = "includedGroupsInAPackage" >
<groups>
<run>
<include name = "includedGroup" />
</run>
</groups>
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
排除一个包中的某些组
<test name = "excludedGroupsInAPackage" >
<groups>
<run>
<exclude name = "excludedGroup" />
</run>
</groups>
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
其能够附带的属性有以下几种,下面对各个属性作单独说明:
(1)、name属性
此属性属于必需要有的,值能够自行设定,此名字会在testNG的报告中看到;
(2)、verbose属性
此属性为指定testNG报告的详细程度,从0开始到10,其中10为最详细,默认生成的xml此属性值为1
(3)、threadPoolSize属性
该属性指定此test的线程池大小,为数字;
@Test(threadPoolSize = 3, invocationCount = 10, timeOut = 10000)
public void testServer() {
}
(4)、invocationCount属性
该属性指定此test的运行次数,为数字,范例如上面的代码所示;
(5)、time-out属性
此属性用于指定超时时间,该suite下全部的用例的超时时间,范例如上面的代码所示;
(6)、group-by-instances属性
此项用于那些有依赖的方法,且被依赖的对象有多个重载对象,由于若是是依赖方法,且该方法有多个重载方法,则默认是会将全部重载方法都跑完再运行被依赖方法,但有时候咱们不想这样,则将此项设置为true便可;
<suite name="Factory" group-by-instances="true">
(7)、preserve-order属性
值可输入true或者false,若是为true,则用例执行会按照在xml中的顺序执行,不然会乱序执行,不添加此属性的话默认是按顺序执行的;
此标签必然是在<test>标签下的,用于标识那些组会被用于测试或者被排除在测试以外,其同级必然要包含一个<classes>标签或者<pakages>标签,用于指定groups来自于哪些包或者类;
以下即为包含一个group,排除一个group的例子:
<groups>
<run>
<include name = "includedGroupName" />
<exclude name = "excludedGroupName" />
</run>
</groups>
高级应用:
<test name="Regression1">
<groups>
<define name="functest">
<include name="windows"/>
<include name="linux"/>
</define>
<define name="all">
<include name="functest"/>
<include name="checkintest"/>
</define>
<run>
<include name="all"/>
</run>
</groups>
<classes>
<class name="test.sample.Test1"/>
</classes>
</test>
其余的话就是测试脚本的选择了,有三种方式:
选择一个包
<packages>
<package name = "packageName" />
</packages>
选择一个类
<classes>
<class name = "className" />
</classes>
选择一个方法
<classes>
<class name = "className" />
<methods>
<include name = "methodName" />
</methods>
</class>
</classes>
这里也支持正则表达式,例如:
<test name="Test1">
<classes>
<class name="example1.Test1">
<methods>
<include name=".*enabledTestMethod.*"/>
<exclude name=".*brokenTestMethod.*"/>
</methods>
</class>
</classes>
</test>