1) TestNG是一个测试框架,其灵感来自JUnit和NUnit的,但引入了一些新的功能,使其功能更强大,使用更方便。
2) TestNG是一个开源自动化测试框架;TestNG表示下一代。 TestNG是类似于JUnit(特别是JUnit 4),但它不是一个JUnit扩展。它的灵感来源于JUnit。它的目的是优于JUnit的,尤其是当测试集成的类。
3) TestNG的创造者是Cedric Beust(塞德里克·博伊斯特)
4) TestNG消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。因为它在很大程度上借鉴了Java注解(JDK5.0引入的)来定义的测试,它也可以告诉你如何使用这个新功能在真实的Java语言生产环境中。
1)注解
2) TestNG使用Java和面向对象的功能
3) 支持综合类测试(例如,默认情况下,没有必要创建一个新的测试每个测试方法的类的实例)
4) 独立的编译时间测试代码运行时配置/数据信息
5) 灵活的运行时配置
6)主要介绍“测试组”。当编译测试,只要问TestNG运行所有的“前端”的测试,或“快”,“慢”,“数据库”等
7) 支持依赖测试方法,并行测试,负载测试,局部故障
8) 灵活的插件API
9) 支持多线程测试
http://pan.baidu.com/s/1hsBClvQ
1. 将解压后的文件..\eclipse-testng离线包\features\org.testng.eclipse_6.9.9.201510270734 文件夹 放到 eclipse-->features目录下
2. 将解压后的文件..\eclipse-testng离线包\plugins\org.testng.eclipse_6.9.8.201510130443 文件夹 放到 eclipse-->plugins目录下
file-->new-->other-->TestNg
<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.9.10</version> <scope>test</scope> </dependency>
<plugin> <!-- testNG插件 --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <!-- 解决Maven test 乱码问题 --> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> <!-- true 关闭测试; false 开启测试; --> <skipTests>false</skipTests> <!-- 包含哪些测试java类 --> <includes> <!-- 任何子目录下包含Test的java类 --> <!--<include>**/*Test.java</include> --> <!-- 任何子目录下已Test开头的java类 --> <!--<include>**/Test*.java</include> --> <!-- 任何子目录下已Test结尾的java类 --> <!--<include>**/*Test.java</include> --> </includes> <!-- 排除哪些测试java类 --> <excludes> <!-- 同上includes --> <!--<exclude>**/*Test.java</exclude> --> </excludes> <!-- 使用XML文件导入需要的测试java类 --> <suiteXmlFiles> <suiteXmlFile>src/test/resources/testng/testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin>
进行测试:
mvn test
打包跳过测试:
mvn package -Dmaven.test.skip=true
注解 描述 @BeforeSuite 注解的方法将只运行一次,运行所有测试前此套件中。 @AfterSuite 注解的方法将只运行一次此套件中的所有测试都运行之后。 @BeforeClass 注解的方法将只运行一次先行先试在当前类中的方法调用。 @AfterClass 注解的方法将只运行一次后已经运行在当前类中的所有测试方法。 @BeforeTest 注解的方法将被运行之前的任何测试方法属于内部类的 <test>标签的运行。 @AfterTest 注解的方法将被运行后,所有的测试方法,属于内部类的<test>标签的运行。 @BeforeGroups 组的列表,这种配置方法将之前运行。此方法是保证在运行属于任何这些组第一个测试方法,该方法被调用。 @AfterGroups 组的名单,这种配置方法后,将运行。此方法是保证运行后不久,最后的测试方法,该方法属于任何这些组被调用。 @BeforeMethod 注解的方法将每个测试方法之前运行。 @AfterMethod 被注释的方法将被运行后,每个测试方法。 @DataProvider 标志着一个方法,提供数据的一个测试方法。注解的方法必须返回一个Object[] [],其中每个对象[]的测试方法的参数列表中可以分配。 该@Test 方法,希望从这个DataProvider的接收数据,需要使用一个dataProvider名称等于这个注解的名字。 @Factory 作为一个工厂,返回TestNG的测试类的对象将被用于标记的方法。该方法必须返回Object[]。 @Listeners 定义一个测试类的监听器。 @Parameters 介绍如何将参数传递给@Test方法。 @Test 标记一个类或方法作为测试的一部分。
TestNG中@Test参数详解 参数名 参数类型 备注 groups String[] 分组测试组名 enabled boolean 标识当前测试是否可用 parameters String[] 和testng.xml配置文件相对应的参数名 dependsOnGroups String[] 当前方法依赖的组列表 dependsOnMethods String[] 当前方法依赖的方法列表 timeOut long 超时时间,单位毫秒 invocationCount int 表示执行的次数 threadPoolSize int 表示线程池内的线程个数 successPercentage int 当前方法期望的成功率 dataProvider String 当前测试方法的dataProvider名称 dataProviderClass Class<?> 当前测试方法用于查找dataProvider的类, 和dataProvider一起出现, dataPrividerClass中的获取参数方法必须为static, 否则出异常 alwaysRun boolean 为true时,总是执行,依赖源执行失败, 方法不被标记为Skips 为false时,依赖源执行失败,方法被标记为Skips description String 当前方法的描述 expectedExceptions Class[] 测试方法期望抛出的异常列表 expectedExceptionsMessageRegExp String 测试方法抛出异常的message信息 suiteName String 测试套件使用的默认名称 testName String 测试使用的默认名称 sequential boolean 为true,当前测试类上的所有方法保证按照顺序运行。 singleThreaded boolean 为true时,表示在这个测试类中的所有方法 在同一个线程中执行 retryAnalyzer Class skipFailedInvocations boolean invocationCount>2时, 其为true时,出现异常时,失败一次,其它的为Skips ignoreMissingDependencies boolean 为true,找不到依赖继续执行 priority int 调度优先级。越小的将被优先调用
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <!-- 当前测试套件名称 --> <suite name="testNG"> <!-- 加载第一个测试类 --> <!-- name : 当前测试名称 --> <!-- verbose: 日子显示级别,0表示不显示,10最高级别 --> <!-- enabled: 当前测试是否可用,true 可用,false 不可用 --> <test name="testParam" verbose="0" enabled="false"> <!-- name : 测试方法参数名,value :测试方法参数值 --> <parameter name="param0" value="第一个参数"></parameter> <parameter name="param1" value="第二个参数"></parameter> <classes> <!-- 加载测试类 --> <class name="com.zzwx.test.testng.TestNGTestParam"/> </classes> </test> <!-- 加载第二个测试类 --> <test name="testGroup" verbose="0" enabled="true" > <!-- 加载测试组信息 --> <groups> <!-- 添加运行组 --> <run> <!-- 需要运行的组名 --> <include name="adminGroup" /> <!-- 不需要运行的组名 --> <exclude name="userGroup" /> </run> </groups> <classes> <!-- 加载测试类 --> <class name="com.zzwx.test.testng.TestNGTestGroup"/> </classes> </test> </suite>
package com.zzwx.test.testng; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; /** * @author Roger * @desc TestNG常规测试 */ publicclass TestNGTest { /** * 开始测试方法前执行的代码 */ @BeforeTest publicvoid testBefore() { System.out.println(this.getClassName() + "before!"); } /** * 执行测试方法 */ @Test publicvoid testNgTest() { System.out.println("helloTestNg"); } /** * 测试方法执行后执行的代码 */ @AfterTest publicvoid testAfter() { System.out.println(this.getClassName() + "after!"); } public String getClassName() { returnthis.getClass().getSimpleName(); } }
生成默认的一个testng.xml执行配置
[TestNG] Running: C:\Users\Administrator.PC-201603081032\AppData\Local\Temp\testng-eclipse-1037823621\testng-customsuite.xml TestNGTest before! hello TestNg TestNGTest after! PASSED: testNgTest =============================================== Default test Tests run: 1, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 1, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by org.testng.reporters.EmailableReporter2@527308ce: 15 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@20ba650b: 0 ms [TestNG] Time taken by org.testng.reporters.jq.Main@30b98167: 61 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@11412a45: 11 ms [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 4 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@1b65c779: 16 ms
package com.zzwx.test.testng; import org.testng.annotations.Test; /** * @author Roger * @desc测试分组 */ publicclass TestNGTestGroup{ @Test(groups = { "adminGroup" }) publicvoid testGroup1() { System.out.println(this.getClassName() + " :adminGroup 1"); } @Test(groups = { "adminGroup" }) publicvoid testGroup11() { System.out.println(this.getClassName() + " :adminGroup 2"); } @Test(groups = { "userGroup" }) publicvoid testGroup2() { System.out.println(this.getClassName() + " :userGroup 1"); } @Test(groups = { "userGroup" }) publicvoid testGroup22() { System.out.println(this.getClassName() + " :userGroup 2"); } public String getClassName() { returnthis.getClass().getSimpleName(); } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="testNG_group"> <!-- TestNG测试组 --> <test name="testGroup" verbose="0" enabled="true" > <groups> <run> <!-- 需要测试的组名 --> <include name="adminGroup" /> <!-- 不需要测试的组名 --> <exclude name="userGroup" /> </run> </groups> <classes> <class name="com.zzwx.test.testng.TestNGTestGroup"/> </classes> </test> </suite>
选择配置文件 -- > Run As --> TestNG Suite
[TestNG] Running: D:\workspace\EclipseWorkSpaceTestNG\testNG-parent\testNG-controller\src\test\resources\testng\testng-module\testng-group.xml TestNGTestGroup : adminGroup 1 TestNGTestGroup : adminGroup 2 =============================================== testNG_group Total tests run: 2, Failures: 0, Skips: 0 ===============================================
package com.zzwx.test.testng; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; /** * @author Roger * @desc异常测试 */ publicclassTestNGTestException { @BeforeTest publicvoid before() { System.out.println(this.getClassName() + "before!"); } /** * 测试异常,并验证异常信息是否匹配 */ @Test(expectedExceptions= NullPointerException.class,expectedExceptionsMessageRegExp = "this is null point") publicvoid testException() { thrownew NullPointerException("this is null point"); } @AfterTest publicvoid after() { System.out.println(this.getClassName() + "after!"); } public String getClassName() { returnthis.getClass().getSimpleName(); } }
[TestNG] Running: C:\Users\Administrator.PC-201603081032\AppData\Local\Temp\testng-eclipse-1504143100\testng-customsuite.xml TestNGTestException before! TestNGTestException after! PASSED: testException =============================================== Default test Tests run: 1, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 1, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by org.testng.reporters.EmailableReporter2@527308ce: 15 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@20ba650b: 0 ms [TestNG] Time taken by org.testng.reporters.jq.Main@30b98167: 47 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@11412a45: 16 ms [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@1b65c779: 15 ms
package com.zzwx.test.testng; import org.testng.annotations.Test; /** * @author Roger * @desc TestNG依赖测试 */ publicclassTestNGTestDepends { public String getClassName() { returnthis.getClass().getSimpleName(); } /** * @alwaysRun = true -- > 依赖源失败后继续执行,方法不被标记为Skips * @alwaysRun = false -- > 依赖源失败后继续执行,方法被标记为Skips, */ @Test(alwaysRun = false, dependsOnMethods = { "testNGTestDepends" }) publicvoid testNGTestBy() { System.out.println(this.getClassName() + " -testNGTestBy"); } @Test publicvoid testNGTestDepends() { System.out.println(this.getClassName() + " -testNGTestDepends"); } }
[TestNG] Running: C:\Users\Administrator.PC-201603081032\AppData\Local\Temp\testng-eclipse-1236448166\testng-customsuite.xml TestNGTestDepends - testNGTestDepends TestNGTestDepends - testNGTestBy PASSED: testNGTestDepends PASSED: testNGTestBy =============================================== Default test Tests run: 2, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 16 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@52988584: 31 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@8cc5c38: 0 ms [TestNG] Time taken by org.testng.reporters.jq.Main@18ada729: 47 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@6db911d2: 15 ms [TestNG] Time taken by org.testng.reporters.EmailableReporter2@5c33e2dc: 0 ms
package com.zzwx.test.entity; import org.testng.annotations.DataProvider; publicclass DataAdmin { @DataProvider(name = "admin") publicstatic Object[][] admin() { returnnew Object[][] { { 10, "admin10", "adminPwd10", false }, {11, "admin11", "adminPwd11", false } }; } }
package com.zzwx.test.testng; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.zzwx.test.entity.Admin; import com.zzwx.test.entity.DataAdmin; /** * @author Roger * @desc通过DataProvider传递参数 */ publicclassTestNGTestDataProvider { public String getClassName() { returnthis.getClass().getSimpleName(); } /** * 参数定义格式必须是一个二维数组,否则抛异常 * * @return Object[][] */ @DataProvider(name = "user") public Object[][] user() { returnnew Object[][] { { "line", "linePassword" }, {"tomcat", "tomcatPassword" } }; } @Test(dataProvider = "user", enabled = false) publicvoid testNGTestDataProvider(String name, String password) { System.out.println(this.getClassName() + "\t name :" + name +" ; password : " + password); } @Test(dataProvider = "admin",dataProviderClass = DataAdmin.class) publicvoid testNGTestDataProviderAdmin(intid,String userName,String password,booleangender) { Adminadmin = new Admin(); admin.setUserName(userName); admin.setGender(gender); admin.setId(id); admin.setPassword(password); System.out.println(admin != null ? admin.toString() : " admin isnull"); } }
[TestNG] Running: C:\Users\Administrator.PC-201603081032\AppData\Local\Temp\testng-eclipse--224274842\testng-customsuite.xml TestNGTestDataProvider name : line ; password : linePassword TestNGTestDataProvider name : tomcat ; password : tomcatPassword Admin [id=10, userName=admin10, password=adminPwd10, gender=false] Admin [id=11, userName=admin11, password=adminPwd11, gender=false] PASSED: testNGTestDataProvider("line", "linePassword") PASSED: testNGTestDataProvider("tomcat", "tomcatPassword") PASSED: testNGTestDataProviderAdmin(10, "admin10", "adminPwd10", false) PASSED: testNGTestDataProviderAdmin(11, "admin11", "adminPwd11", false) =============================================== Default test Tests run: 4, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 4, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by org.testng.reporters.EmailableReporter2@27242aae: 16 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@5dfeaee5: 0 ms [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@2670d85b: 16 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@4f70a570: 15 ms [TestNG] Time taken by org.testng.reporters.jq.Main@4afaa1a4: 47 ms
package com.zzwx.test.testng; import org.testng.annotations.Parameters; import org.testng.annotations.Test; /** * @author Roger * @desc测试参数化 */ publicclass TestNGTestParam{ public String getClassName() { returnthis.getClass().getSimpleName(); } /** * [Parameters] 数组中的参数名必须和testng.xml中的参数名一致,最好的是顺序都一致,以免有影响 * * @param param0 * 此处的参数值与配置文件的参数位置第一个等值 * @param param1 * 此处的参数值与配置文件的参数位置第二个等值 */ @Test @Parameters({ "param0", "param1", "intParam", "boolParam" }) publicvoid testNGTestParam(String param0, String param1, intintParam, booleanboolParam) { System.out.println(this.getClassName() + " \tparam0 : " + param0 +" ; param1 : " + param1 + " ; intParam : " + intParam +" ; boolParam : " + boolParam); } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="testNG_param"> <!-- TestNG 参数化测试 --> <test name="testParam" verbose="0" enabled="true"> <parameter name="param0" value="第一个参数"></parameter> <parameter name="param1" value="第二个参数"></parameter> <parameter name="intParam" value="1"></parameter> <parameter name="boolParam" value="false"></parameter> <classes> <class name="com.zzwx.test.testng.TestNGTestParam"/> </classes> </test> </suite>
[TestNG] Running: D:\workspace\EclipseWorkSpaceTestNG\testNG-parent\testNG-controller\src\test\resources\testng\testng-module\testng-param.xml TestNGTestParam param0 : 第一个参数 ; param1 : 第二个参数 ; intParam : 1 ; boolParam : false =============================================== testNG_param Total tests run: 1, Failures: 0, Skips: 0 ===============================================
package com.zzwx.test.testng; import java.util.concurrent.atomic.AtomicInteger; import org.testng.annotations.Test; /** * @author Roger * @desc TestNG多线程测试 */ publicclass TestNGTestThread{ privatestatic AtomicInteger sum = newAtomicInteger(1); privatestaticintb = 0; /** * @threadPoolSize-->表示执行的线程池的大小 * @invocationCount-->表示执行的次数 * @timeOut-->超时时间(毫秒) */ @Test(threadPoolSize =3, invocationCount = 10, timeOut = 1000) publicvoid testNGTestThread() { System.out.println("[ " + this.getcurrentThreadId() + " ]........" +sum.getAndIncrement() + ".........." + (b++)); } public String getClassName() { returnthis.getClass().getSimpleName(); } public String getcurrentThreadName() { return Thread.currentThread().getName(); } publiclong getcurrentThreadId(){ return Thread.currentThread().getId(); } }
[TestNG] Running: C:\Users\Administrator.PC-201603081032\AppData\Local\Temp\testng-eclipse-989053503\testng-customsuite.xml [ThreadUtil] Starting executor timeOut:1000ms workers:10 threadPoolSize:3 [ 10 ]........1..........0 [ 12 ]........3..........1 [ 11 ]........2..........0 [ 11 ]........4..........2 [ 12 ]........5..........3 [ 11 ]........6..........4 [ 12 ]........7..........5 [ 10 ]........8..........6 [ 11 ]........9..........7 [ 12 ]........10..........8 PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread PASSED: testNGTestThread =============================================== Default test Tests run: 10, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 10, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by org.testng.reporters.jq.Main@876e4b8: 64 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@29df7322: 15 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@35ddb0af: 16 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@2cc2c69f: 15 ms [TestNG] Time taken by org.testng.reporters.EmailableReporter2@75565551: 0 ms [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms
package com.zzwx.test.testng; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; /** * @author Roger * @desc TestNG常规测试 */ publicclass TestNGTest { /** * 开始测试方法前执行的代码 */ @BeforeTest publicvoid testBefore() { System.out.println(this.getClassName() + "before!"); } /** * 执行测试方法 */ @Test publicvoid testNgTest() { System.out.println("helloTestNg"); } /** * 测试方法执行后执行的代码 */ @AfterTest publicvoid testAfter() { System.out.println(this.getClassName() + "after!"); } public String getClassName() { returnthis.getClass().getSimpleName(); } }
package com.zzwx.test.testng; import org.testng.TestNG; /** * @author Roger * @desc通过Main函数调用TestNG测试方法 */ publicclass TestMain { publicstaticvoid main(String[] args) { TestNGtestng = new TestNG(); testng.setTestClasses(new Class[]{TestNGTest.class}); testng.run(); } }
[TestNG] Running: Command line suite TestNGTest before! hello TestNg TestNGTest after! =============================================== Command line suite Total tests run: 1, Failures: 0,Skips: 0 ===============================================
本文出自 “10950988” 博客,请务必保留此出处http://10960988.blog.51cto.com/10950988/1791040
原文地址:http://10960988.blog.51cto.com/10950988/1791040