TestNG简介

Testng是一套开源测试框架,是从Junit继承而来,testng意为test next generation

创建maven项目,添加依赖

        <dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>

常用注解

@BeforeSuite / @AfterSuite
@BeforeTest / @AfterTest
@BeforeClass / @AfterClass,在类运行之前/后运行
@BeforeMethod / @AfterMethod,在测试方法之前/后运行
 
package com.qzcsbj;

import org.testng.annotations.*;
import org.testng.annotations.Test; /**
* @描述 : <...>
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
*/
public class TestAnnotation {
@Test
public void test(){
System.out.println("TestAnnotation.test");
System.out.println("线程ID:" + Thread.currentThread().getId());
} @Test
public void test2(){
System.out.println("TestAnnotation.test2");
} @BeforeMethod
public void beforeMethodTest(){
System.out.println("TestAnnotation.beforeMethodTest");
} @AfterMethod
public void afterMethodTest(){
System.out.println("TestAnnotation.afterMethodTest");
} @BeforeClass
public void beforeClassTest(){
System.out.println("TestAnnotation.beforeClassTest");
} @AfterClass
public void afterClassTest(){
System.out.println("TestAnnotation.afterClassTest");
} @BeforeSuite
public void beforeSuiteTest(){
System.out.println("TestAnnotation.beforeSuiteTest");
} @AfterSuite
public void afterSuiteTest(){
System.out.println("TestAnnotation.afterSuiteTest");
}
}
 

输出结果:

TestAnnotation.beforeSuiteTest
TestAnnotation.beforeClassTest
TestAnnotation.beforeMethodTest
TestAnnotation.test
线程ID:1
TestAnnotation.afterMethodTest
TestAnnotation.beforeMethodTest
TestAnnotation.test2
TestAnnotation.afterMethodTest
TestAnnotation.afterClassTest
TestAnnotation.afterSuiteTest

安装插件Create TestNG XML

搜索:Create TestNG XML

安装

重启后

创建xml文件

在resources下创建suite.xml,文件名随意,只要内容符合要求就可以了
 
suite:套件,包含一个或多个test
  test:测试集,包含一个或多个classes
    classes:测试类集合,包含一个或多个class
      class:测试类,包含一个或多个方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<!--<test verbose="2" preserve-order="true" name="test">-->
<test name="test">
<classes>
<class name="com.qzcsbj.TestAnnotation"/>
</classes>
</test>
<test name="test2">
<classes>
<class name="com.qzcsbj.TestAnnotationB">
<methods>
<include name="testb"/> <!--指定要运行的方法-->
</methods>
</class>
</classes>
</test>
</suite>

套件测试

第一个类

package com.qzcsbj;

import org.testng.annotations.*;
import org.testng.annotations.Test; /**
* @描述 : <...>
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
*/
public class TestAnnotation {
@Test
public void test(){
System.out.println("TestAnnotation.test");
System.out.println("线程ID:" + Thread.currentThread().getId());
} @Test
public void test2(){
System.out.println("TestAnnotation.test2");
} @BeforeMethod
public void beforeMethodTest(){
System.out.println("TestAnnotation.beforeMethodTest");
} @AfterMethod
public void afterMethodTest(){
System.out.println("TestAnnotation.afterMethodTest");
} @BeforeClass
public void beforeClassTest(){
System.out.println("TestAnnotation.beforeClassTest");
} @AfterClass
public void afterClassTest(){
System.out.println("TestAnnotation.afterClassTest");
} @BeforeSuite
public void beforeSuiteTest(){
System.out.println("TestAnnotation.beforeSuiteTest");
} @AfterSuite
public void afterSuiteTest(){
System.out.println("TestAnnotation.afterSuiteTest");
}
}

  

第二个类

package com.qzcsbj;

import org.testng.annotations.*;
import org.testng.annotations.Test; /**
* @描述 : <...>
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
*/
public class TestAnnotationB {
@Test
public void testb(){
System.out.println("TestAnnotation.testb==");
System.out.println("线程ID:" + Thread.currentThread().getId());
} @Test
public void testb2(){
System.out.println("TestAnnotationB.testb2==");
} @BeforeMethod
public void beforeMethodTestb(){
System.out.println("TestAnnotationB.beforeMethodTestb==");
} @AfterMethod
public void afterMethodTestb(){
System.out.println("TestAnnotationB.afterMethodTestb==");
} @BeforeClass
public void beforeClassTestb(){
System.out.println("TestAnnotationB.beforeClassTestb==");
} @AfterClass
public void afterClassTestb(){
System.out.println("TestAnnotationB.afterClassTestb==");
} @BeforeSuite
public void beforeSuiteTestb(){
System.out.println("TestAnnotationB.beforeSuiteTestb==");
} @AfterSuite
public void afterSuiteTestb(){
System.out.println("TestAnnotationB.afterSuiteTestb==");
}
}

输出结果:

TestAnnotation.beforeSuiteTest
TestAnnotationB.beforeSuiteTestb== TestAnnotation.beforeClassTest
TestAnnotation.beforeMethodTest
TestAnnotation.test
线程ID:1
TestAnnotation.afterMethodTest TestAnnotation.beforeMethodTest
TestAnnotation.test2
TestAnnotation.afterMethodTest
TestAnnotation.afterClassTest TestAnnotationB.beforeClassTestb==
TestAnnotationB.beforeMethodTestb==
TestAnnotation.testb==
线程ID:1 TestAnnotationB.afterMethodTestb==
TestAnnotationB.afterClassTestb== TestAnnotation.afterSuiteTest
TestAnnotationB.afterSuiteTestb==

忽略测试

测试过程中,问题还没解决,可以先忽略,也就是不执行此方法

package com.qzcsbj;

import org.testng.annotations.Test;

/**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestIgnore {
@Test
public void testa(){
System.out.println("TestIgnore.testa");
} @Test(enabled = true)
public void testb(){
System.out.println("TestIgnore.testb");
} @Test(enabled = false)
public void testc(){
System.out.println("TestIgnore.testc");
}
}

运行结果:

TestIgnore.testa
TestIgnore.testb

分组测试

场景︰只想执行个别或者某一部分的测试用例

package com.qzcsbj;

import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; /**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestGroups {
@Test(groups = "login")
public void testa(){
System.out.println("TestIgnore.testa");
} @Test(groups = "submitOrder")
public void testb(){
System.out.println("TestIgnore.testb");
} @Test(groups = "submitOrder")
public void testc(){
System.out.println("TestIgnore.testc");
} @BeforeGroups("submitOrder")
public void testBeforeGroups(){
System.out.println("TestGroups.testBeforeGroups");
} @AfterGroups("submitOrder")
public void testAfterGroup(){
System.out.println("TestGroups.testAfterGroup");
}
}

  

输出结果:

TestIgnore.testa
TestGroups.testBeforeGroups
TestIgnore.testb
TestIgnore.testc
TestGroups.testAfterGroup

xml方式

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<!--<test verbose="2" preserve-order="true" name="test">-->
<test name="test"> <!--test必须有name属性-->
<groups>
<run>
<include name="submitOrder"/>
</run>
</groups>
<classes>
<class name="com.qzcsbj.TestGroups"/>
</classes>
</test>
</suite>

输出结果:

TestGroups.testBeforeGroups
TestIgnore.testb
TestIgnore.testc
TestGroups.testAfterGroup

依赖测试

字符串数组,默认是空

dependsOnMethods和BeforeMethod的区别是: BeforeMethod是每个方法前都要执行,而dependsOnMethods只是依赖的方法前执行

package com.qzcsbj;

import org.testng.annotations.Test;

/**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestDepend {
@Test(dependsOnMethods = {"test2"})
public void test(){
System.out.println("TestAnnotation.test");
} @Test
public void test2(){
System.out.println("TestAnnotation.test2");
}
}

  

运行结果:

TestAnnotation.test2
TestAnnotation.test

如果被依赖方法执行失败,有依赖关系的方法不会被执行;

应用场景,登录失败,就不能进行下单等操作

package com.qzcsbj;

import org.testng.annotations.Test;

/**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestDepend {
@Test(dependsOnMethods = {"test2"})
public void test(){
System.out.println("TestAnnotation.test");
} @Test
public void test2(){
System.out.println("TestAnnotation.test2");
throw new RuntimeException(); // 抛出一个异常
}
}

运行结果:

TestAnnotation.test2

java.lang.RuntimeException
at com.qzcsbj.TestDepend.test2(TestDepend.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

超时

timeout属性的单位为毫秒。

package com.qzcsbj;

import org.testng.annotations.Test;
/**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestTimeOut {
@Test(timeOut = 1000) // 单位为毫秒值,期望在1秒内得到结果
public void test() throws InterruptedException {
System.out.println("TestTimeOut.test");
Thread.sleep(500);
} @Test(timeOut = 1000)
public void test2() throws InterruptedException {
System.out.println("TestTimeOut.test2");
for (int i = 10; i > 0; i--) {
Thread.sleep(101);
System.out.println(i);
}
System.out.println("执行结束。");
}
}

输出结果:

TestTimeOut.test2
10
9
8
7
6
5
4
3
2 org.testng.internal.thread.ThreadTimeoutException: Method com.qzcsbj.TestTimeOut.test2() didn't finish within the time-out 1000 at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1953)
at java.util.concurrent.ThreadPoolExecutor.tryTerminate(ThreadPoolExecutor.java:716)
at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1014)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

断言

package com.qzcsbj;

/**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class Add {
public int sum(int a, int b){
return a+b;
}
}
package com.qzcsbj;

import org.testng.Assert;
import org.testng.annotations.Test; public class MyTest {
@Test
public void test(){
Add add = new Add();
int actual = add.sum(1, 2);
int expect = 2;
Assert.assertEquals(actual,expect);
}
}

参数化(数据驱动测试)

两种方式向测试方法传递参数:

  利用testng.xml定义parameter

  利用DataProviders

xml文件参数化

package com.qzcsbj;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test; /**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestParameter {
@Test
@Parameters({"name","id"})
public void test(String name, int id){
System.out.println("name=" + name + ", id=" + id);
}
}

  

xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<!--<test verbose="2" preserve-order="true" name="test">-->
<test name="test"> <!--test必须有name属性-->
<classes>
<class name="com.qzcsbj.TestParameter">
<parameter name="name" value="qzcsbj"/>
<parameter name="id" value="1"/>
</class>
</classes>
</test>
</suite>

  

运行结果:

name=qzcsbj, id=1

DataProvider参数化

代码和数据未分离
package com.qzcsbj;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; /**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class TestDataProvider {
@Test(dataProvider="data") // 和下面的name对应起来
public void testDataProvider(String name, int id){
System.out.println("name=" + name + ", id=" + id);
}
@DataProvider(name = "data") // 如果没有指定name,上面就写下面的方法名:providerData
public Object[][] providerData(){
Object[][] datas = new Object[][]{
{"zhangsan",1001},
{"lisi",1002},
{"wangwu",1003}
};
return datas;
}
}

  

运行结果:

name=zhangsan, id=1001
name=lisi, id=1002
name=wangwu, id=1003
代码和数据分离,数据存放在excel中

sheet名为data

ExcelUtil.java

package com.qzcsbj;

import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays; /**
* @公众号 : 全栈测试笔记
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <>
*/
public class ExcelUtil {
// 方法也可以根据情况定义更多参数,比如读取excel的列范围
public static Object[][] getdataFromExcel(String excelPath){
Object[][] datas = null;
try {
// 获取workbook对象
Workbook workbook = WorkbookFactory.create(new File(excelPath));
// 获取sheet对象
Sheet sheet = workbook.getSheet("data");
datas = new Object[4][2];
// 获取行
for (int i = 1; i < 5; i++) {
Row row = sheet.getRow(i);
// 获取列
for (int j=0; j<=1;j++){
Cell cell = row.getCell(j);
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
datas[i-1][j] = value;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return datas;
} public static void main(String[] args) {
String excelPath = "E:\\case.xlsx";
Object[][] datas = getdataFromExcel(excelPath);
for (Object[] data : datas) {
System.out.println(Arrays.toString(data));
}
}
}

上面读取到的数据

LoginCase.java

package com.qzcsbj;

import com.qzcsbj.HttpPostRequest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.HashMap; /**
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <...>
*/
public class LoginCase {
@Test(dataProvider = "datasFromExcel") // 多条数据,且数据和代码分离
public void test(String username, String password){
String url = "http://127.0.0.1:9999/login";
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", username);
params.put("password", password);
String res = HttpPostRequest.postRequest(url, params);
System.out.println("入参:username=" + username + ", password=" + password);
System.out.println("响应:" + res);
System.out.println("============================\n");
} @DataProvider(name = "datasFromExcel")
public Object[][] datasFromExcel(){
Object[][] datas = ExcelUtil.getdataFromExcel("E:\\case.xlsx");
return datas;
}
}

进一步优化

把用例数据都放到excel中,读取excel文件,写一个CaseUtil工具类,根据接口编号来获取这个接口的测试数据,并获取指定列,比如:

Object[][] datas = CaseUtil.getDataByApiId("1",columns);

【bak】https://www.cnblogs.com/uncleyong/p/15855473.html

原文:https://www.cnblogs.com/uncleyong/p/15867747.html

TestNG基本使用的更多相关文章

  1. TestNG 入门教程

    原文出处:http://www.cnblogs.com/TankXiao/p/3888070.html 阅读目录 TestNG介绍 在Eclipse中在线安装TestNG 在Eclipse中离线安装T ...

  2. JUnit 4 与 TestNG 对比

    原文出处: 付学良的网志 原文出处2: http://www.importnew.com/16270.html -------------------------------------------- ...

  3. JAVA+Maven+TestNG搭建接口测试框架及实例

    1.配置JDK 见另一篇博客:http://www.cnblogs.com/testlurunxiu/p/5933912.html 2.安装Eclipse以及TestNG Eclipse下载地址:ht ...

  4. Idea+TestNg配置test-output输出

    说明:testNG的工程我是使用eclipse创建的,直接导入到idea中,运行test时不会生产test-output,只能在idea的控制台中查看运行结果,然后到处报告,经过不懈的百度终于找到怎么 ...

  5. testng 失败自动截图

    testng执行case failed ,testng Listener会捕获执行失败,如果要实现失败自动截图,需要重写Listener的onTestFailure方法 那么首先新建一个Listene ...

  6. 两种方式testng dataprovider结合csv做测试驱动

    方式一: 第一.读取csv数据源码 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...

  7. java分享第十九天(TestNg的IReporter接口的使用)

     IReporter接口是干嘛的?就是让用户自定义报告的,很多人想要自定义报告,于是乎找各种插件,比如什么testng-xslt啊,reportng啊,各种配置,最后出来的结果,还不能定制化,但为什么 ...

  8. java分享第十八天-02( java结合testng,利用XML做数据源的数据驱动)

    testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以XML为例:备注:@DataProvider的返回值类 ...

  9. java分享第十四天(TestNG Assert详解)

     TestNG Assert 详解org.testng.Assert 用来校验接口测试的结果,那么它提供哪些方法呢? 中心为Assert测试类,一级节点为方法例如assertEquals,二级结点为参 ...

  10. TestNG Assert 详解

    org.testng.Assert 用来校验接口测试的结果,那么它提供哪些方法呢? 中心为Assert测试类,一级节点为方法例如assertEquals,二级结点为参数类型及参数个数,double 3 ...

随机推荐

  1. MongDB日志分析

    Result文件数据说明: Ip:106.39.41.166,(城市) Date:10/Nov/2016:00:01:02 +0800,(日期) Day:10,(天数) Traffic: 54 ,(流 ...

  2. vue学习4-class和sytle绑定

    #### Class绑定: 1. 通过数组的方式来实现: 2. 通过对象的方式来实现: 通过对象: 通过数组,通过数组是把多个style样式对象添加进去:

  3. 微服务架构 | *2.3 Spring Cloud 启动及加载配置文件源码分析(以 Nacos 为例)

    目录 前言 1. Spring Cloud 什么时候加载配置文件 2. 准备 Environment 配置环境 2.1 配置 Environment 环境 SpringApplication.prep ...

  4. java接口概述及特点

    1 package face_09; 2 3 4 5 6 abstract class AbsDemo{ 7 abstract void show1(); 8 abstract void show2( ...

  5. 聊聊HTTPS和SSL协议

    本文为转载,原文链接http://www.techug.com/https-ssl-tls,作者不详. 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识. 1. 大致了解几个基本术语(H ...

  6. 什么是VPC

    1 什么是私有网络(VPC) 私有网络是一块可用户自定义的网络空间,您可以在私有网络内部署云主机.负载均衡.数据库.Nosql快存储等云服务资源.您可自由划分网段.制定路由策略.私有网络可以配置公网网 ...

  7. 了解promise、promise对象

    Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象. 所谓Pr ...

  8. JAVA类加载器二 通过类加载器读取资源文件

    感谢原文作者:不将就! 原文链接:https://www.cnblogs.com/byron0918/p/5770684.html 一.getResourceAsStream方法 getResourc ...

  9. 模拟dom结构

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. K8s多节点部署+负载均衡+keepalived ——囊萤映雪

    K8s多节点部署+负载均衡+keepalived --囊萤映雪 1.多节点master2 部署 2.负载均衡部署+keepalived 1.多节点master2部署: #从master01节点上拷贝证 ...