UI自动化测试(六)TestNG操作详解
在编写TestNG代码的时候,若没有下载TestNG的jar包的话,代码会出错,下载jar包方法见该链接中java+selenium环境搭建的第二步即可:http://www.cnblogs.com/hong-fithing/p/7622215.html
运行测试步骤方法有如下两种:
1、 直接在Eclipse运行testNG的测试用例, 在代码编辑区域鼠标右键, 选择Run as ->testNG Test
2、 在工程的根目录下, 建立testng.xml文件, 并在文件中输入配置内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="suite1">
<test name="test1">
<classes>
<class name="com.ui.day4.CalcTest" />
<class name="com.testng.demo_1" />
</classes>
</test>
</suite>
然后在工程中的testNG.xml上方鼠标右键单击, 在弹出的菜单中选择Run as ->Test Suite即可运行测试用例,suite代表一个XML文件。 它可以包含一个或多个测试, 并被定义由<suite>标记标签<test>代表一个测试, 并可以包含一个或多个TestNG的类<class>的标签代表一个TestNG的类是一个Java类,它包含至少一个TestNG的注解。它可以包含一个或多个测试方法。
执行结果查看方式:
1、 在Console可以查看测试结果
2、 testNG的Results可以查看
3、 testNG的Html格式测试报告, 该测试报告存在与工程目录下的“test-output”目录下,emailable-report.html和index.html。


TestNG常用注解annotation
注解 | 描述 |
@BeforeSuite | 被注释的方法将在所有测试运行前运行(相当于前置条件) |
@AfterSuite |
被注释的方法将在所有测试运行后运行比如关闭浏览器(使执行其他用例时处于初始状态) |
@BeforeTest | 被注释的方法将在测试运行前运行 |
@AfterTest | 被注释的方法将在测试运行后运行 |
@BeforeGroups |
被配置的方法将在列表中的gourp前运行。这个方法保证在第一个属于这些组的测试方法调用 前立即执行 |
@AfterGroups |
被配置的方法将在列表中的gourp后运行。这个方法保证在最后一个属于这些组的测试方法调 用后立即执行 |
@BeforeClass | 被注释的方法将在当前类的第一个测试方法调用前运行 |
@AfterClass | 被注释的方法将在当前类的所有测试方法调用后运行 |
@BeforeMethod | 被注释的方法将在每一个测试方法调用前运行 |
@AfterMethod | 被注释的方法将在每一个测试方法调用后运行 |
@DataProvider |
标记一个方法用于为测试方法提供数据。 被注释的方法必须返回Object[][],其中每个Object[] 可以指派为这个测试方法的参数列表。从这个DataProvider接收数@Test方法需要使用一个和 当前注释相同名称的dataProvider名称 |
@Factory |
标记方法作为一个返回对象的工厂, 这些对象将被TestNG用于作为测试类。这个方法必须返回 Object[] |
@Listeners | 定义一个测试类的监听器 |
@Parameters | 描述如何传递参数给@Test方法 |
@Test | 标记一个类或方法作为测试的一部分 |
备注:
Before开头的注解一般用于初始化环境、 准备测试环境
after开头的注解一般用于执行测试的环境清理工作
DataProvider一般用作参数化用的, 属于数据驱动自动化(即不同的测试数据测试相同的测试逻辑)
Listeners 自定义日志或者监控一些testNG用例执行成功或者失败的时候做些特别的事情
Parameters可以把xml文件定义的参数传递到测试程序或者测试类中来使用
public class yihuqingjiu_test_demo { @Test
public void testCase1() {
System.out.println("in test case 1");
}
@Test
public void testCase2() {
System.out.println("in test case 2");
}
@BeforeMethod
public void beforeMethod() {
System.out.println("in beforeMethod");
}
@AfterMethod
public void afterMethod() {
System.out.println("in afterMethod");
}
@BeforeClass
public void beforeClass() {
System.out.println("in beforeClass");
}
@AfterClass
public void afterClass() {
System.out.println("in afterClass");
}
@BeforeTest
public void beforeTest() {
System.out.println("in beforeTest");
}
@AfterTest
public void afterTest() {
System.out.println("in afterTest");
}
@BeforeSuite
public void beforeSuite() {
System.out.println("in beforeSuite");
}
@AfterSuite
public void afterSuite() {
System.out.println("in afterSuite");
} }
运行结果:
in beforeSuite
in beforeTest
in beforeClass
in beforeMethod
in test case 1
in afterMethod
in beforeMethod
in test case 2
in afterMethod
in afterClass
in afterTest
首先beforeSuite()方法执行一次。
最后afterSuite的()方法执行一次。
其次方法 beforeTest(), beforeClass(), afterClass() 和afterTest() 方法各执行一次。
beforeMethod()方法在执行每个测试用例之前执行一次。
afterMethod()方法在执行每个测试用例之后执行一次。
TestNG测试套件
测试套件是为了测试软件程序的行为或一系列行为, 是一个集合。 在TestNG中, 不能在测试源代码中引入测试集合, 但可以用testng.xml文件来进行测试套件的配置。
Testng.xml文件节点属性
suite常用属性介绍 | |
注解 | 描述 |
@name | suite的名称, 必须参数 |
@verbose | 命令行信息打印等级, 不会影响测试报告输出内容; 可选值(1|2|3|4|5) |
@parallel |
是否多线程并发运行测试; 可选值(false | methods | tests | classes |instances)默认 "false" |
@thread-count | 当为并发执行时的线程池数量, 默认为"5" |
@annotations | 获取注解的位置, 如果为"javadoc", 则使用javadoc注解, 否则使用jdk注解 |
junit | 是否以Junit模式运行, 可选值(true | false), 默认"false" |
@time-out | 为具体执行单元设定一个超时时间, 具体参照parallel的执行单元设置; 单位为毫秒 |
test常用属性说明 | |
注解 | 描述 |
@name | test的名字, 必选参数; 测试报告中会有体现 |
@verbose | 命令行信息打印等级, 不会影响测试报告输出内容; 可选值(1|2|3|4|5) |
@parallel |
是否多线程并发运行测试; 可选值(false | methods | tests | classes |instances)默认 "false" |
@thread-count | 当为并发执行时的线程池数量, 默认为"5" |
@annotations | 获取注解的位置, 如果为"javadoc", 则使用javadoc注解, 否则使用jdk5注解 |
@time-out | 为具体执行单元设定一个超时时间, 具体参照parallel的执行单元设置; 单位为毫秒 |
@enabled | 设置当前test是否生效, 可选值(true | false), 默认"true" |
testng.xml中有<suite>根标签。 它描述了一个测试套件, <suite>由一个或多个<test>区段组成, 如下testng.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="exampletest1">
<classes>
<class name="com.ui.day1.test1" />
7 </classes>
</test>
<test name="exampletest2">
<class name="com.ui.day2.test2">
<methods>
<include name="test01"></include>
</methods>
</class>
</test>
</suite>
TestNG忽略测试
当测试用例还没准备好,可以给测试用例加上@Test(enable =false),来禁用此测试用例。
代码实现:
@Test(enabled = false)
public void add(){
Assert.assertEquals(a.add(5, 6), 11);
}
TestNG分组测试
顾名思义,是将不同的用例分组,然后再testng.xml文件中配置信息,而执行相应组的用例,代码实现如下,仅供参考:
package com.ui.day4; import org.testng.Assert;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test; public class yihuqingjiu_test_group {
ca a;
@BeforeSuite(groups = {"冒烟","回归"})
public void reday() {
a = new ca();
}
@Test(groups = "冒烟")
public void add() {
Assert.assertEquals(a.add(5, 6), 11);
}
@Test(groups = "冒烟")
public void min() {
Assert.assertEquals(a.minus(6, 5), 1);
}
@Test(groups = "冒烟")
public void cheng() {
Assert.assertEquals(a.cheng(6, 5), 30);
}
@Test(groups = "回归")
public void cheng1() {
Assert.assertEquals(a.cheng(6, 5), 30);
}
@Test(groups = "回归")
public void chu() {
Assert.assertEquals(a.chu(5, 5), 1);
}
}
testng.xml文件配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="3">
<test name="test_one">
<groups>
<run>
<include name="回归" />
</run>
</groups>
<classes>
<class name="com.ui.day4.test_group"></class>
</classes>
</test>
</suite>
TestNG依赖测试
按顺序来调用测试用例,那么测试用例之间就存在依赖关系,TestNG支持测试用例之间的依赖。TestNG中通过dependsOnMethods属性来配置依赖方法。
实现如下:
@Test(dependsOnMethods = { "minus" })
public void add() {
Assert.assertEquals(a.add(5, 6), 11);
}
备注: add测试用例执行的前提条件是必须minus测试方法执行,如果minus用例的属性设置为enabled = false,那么执行测试的时候就会报错,因为minus不执行。 注意:被依赖的测试用例必须执行成功才运行下一个测试用例,dependsOnGroups依赖于测试组
TestNG自定义执行顺序
按照一定的顺序去执行测试方法, 通过priority属性去设 置,如下代码实现:
public class yihuqingjiu_demo {
@Test(priority=2)
public void print3(){
System.out.println("壶");
}
@Test(priority=0)
public void print1(){
System.out.println("温");
}
@Test(priority=1)
public void print2(){
System.out.println("一");
}
@Test(priority=4)
public void print5(){
System.out.println("酒");
}
@Test(priority=3)
public void print4(){
System.out.println("清");
}
}
执行顺序为print1--->print2--->print3--->print4--->print5
属性值为0代表最高优先级
还可以在testng.xml文件中设置,设置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="test" preserve-order="true">
<classes>
<class name="com.ui.day4.test_demo">
<methods>
<include name="print5" />
<include name="print2" />
<include name="print4" />
<include name="print1" />
<include name="print3" />
</methods>
</class>
</classes>
</test>
</suite>
preserve-order属性设置为true
依据include配置的顺序执行测试方法
TestNG参数化测试
软件测试中, 经常需要测试大量的数据集。 测试代码的逻辑完全一样, 只是测试的参数不一样。 这样我们就需要一种 “传递测试参数的机制” 。 避免写重复的测试代码。
TestNG提供了2种传递参数的方式:
第一种: testng.xml 方式使代码和测试数据分离,方便维护;
第二种: @DataProvider能够提供比较复杂的参数。(也叫data-driven testing)
使用testng.xml设置参数:
1、 参数在xml文件中可以在suite级别定义, 也可以在test级别定义;
2、 TestNG会尝试先在包含当前类的test标签中寻找参数, 如果没找到则在上层的suite标签中查找。 即在test标签中相同的参数对当前类当前方法的优先级比较高。
3、 TestNG支持这种传参方式的类型如下:
String、 int/Integer、 boolean/Boolean、 byte/Byte、 char/Character、double/Double、 float/Float、
long/Long、 short/Short
使用@DataProvider方式传参数:
只提供了一个字符串属性:名称,供测试方法作为传递参数的annotation使用两种DataProvider,一种是返回一个二维数组对象; 另外一种DataProvider是返回一个Iterator
DataProvider可以向测试方法传递任意类型任意数目的参数利用DataProvider提供不同的参数集合对一个测试方法进行多次调用
@DataProvider和testNG.xml两种方式的比较
public class NewTest {
WebDriver driver; @BeforeSuite
public void reday(){
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
} @Test(priority=0)
public void index() throws Exception{
driver.get("http://127.0.0.1/iwebshop/");
String title=driver.getTitle();
//断言
//括号中前者是实际结果,后者是预期结果
Assert.assertEquals(title,"iWebShop开源电子商务平台");
Thread.sleep(2000);
} @Test(priority=1)
public void login() throws Exception{
driver.findElement(By.cssSelector("p.loginfo a")).click();
Thread.sleep(2000);
} @DataProvider(name="test")
public static Object[][] obj(){
return new Object[][]{{"username","654321"},{"username","123456"},{"username","654321"}};
}
@Test(dataProvider="test",priority=2)
public void userpassword(String a,String b) throws Exception {
driver.findElement(By.className("gray")).sendKeys(a);
Thread.sleep(1000);
driver.findElement(By.cssSelector("input[name='password']")).sendKeys(b);
Thread.sleep(1000);
System.out.println(a+":"+b);
driver.findElement(By.className("submit_login")).click();
Thread.sleep(2000); }
用户名和密码依次传递给变量a和b,重复登录操作
UI自动化测试(六)TestNG操作详解的更多相关文章
- UI第六节——UINavigationController 详解
1. UINavigationController 是一个容器类.里面盛放的是UIViewController. 容器的意思是,如果你不放入UIViewController,里面就是空的,什么也没有. ...
- TestNG操作详解
运行测试步骤方法有如下两种: 1. 直接在Eclipse运行testNG的测试用例, 在代码编辑区域鼠标右键, 选择Run as ->testNG Test 2. 在工程的根目录下, 建立tes ...
- Django框架 之 ORM查询操作详解
Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...
- MongoDB各种查询操作详解
这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询.关联查询.数组查询等,需要的朋友可以参考下 一.find操作 MongoDB中使用find来进行查询,通过指定find的第一个参数可 ...
- C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)
前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- windows phone 8.1开发SQlite数据库操作详解
原文出自:http://www.bcmeng.com/windows-phone-sqlite1/ 本文小梦将和大家分享WP8.1中SQlite数据库的基本操作:(最后有整个示例的源码)(希望能通过本 ...
- VC++常用数据类型及其操作详解
原文地址:http://blog.csdn.net/ithomer/article/details/5019367 VC++常用数据类型及其操作详解 一.VC常用数据类型列表 二.常用数据类型转化 2 ...
随机推荐
- Objective-C 中的协议(@protocol)和接口(@interface)的区别
Objective-C 中的协议(@protocol),依照我的理解,就是C#, Java, Pascal等语言中的接口(Interface).协议本身不实现任何方法,只是声明方法,使用协议的类必须实 ...
- 调试技巧 ------ printf 的使用技巧
编译器宏:__FUNCTION__,__FILE__,__LINE__ #define __debug #ifdef __debug //#define debug(format,...) print ...
- Qt error ------ 'XXX' has not been declared
1.头文件没加 2.调用函数者的头文件在XXX头文件的下方
- Nginx利用lua剪辑FastDFS图片
Nginx利用lua剪辑FastDFS中的图片 我们经常用FastDFS来做图片服务器,通过nginx来上传或者获取图片.本文要实现的功能是,当客户端要获取不同尺寸的图片是,lua根据url中的尺寸大 ...
- Hadoop基础-MapReduce的Partitioner用法案例
Hadoop基础-MapReduce的Partitioner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Partitioner关键代码剖析 1>.返回的分区号 ...
- bzoj千题计划199:bzoj1055: [HAOI2008]玩具取名
http://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间DP dp[i][j][k] 表示区间[i,j]能否合成k #include<cst ...
- 使用mybatisgenerator 辅助工具逆向工程
使用mybatisgenerator 辅助工具生成单表的dao层接口,mapper xml 文件以及实体类,复杂的还得人手动去编写哈...所以我也不觉得这玩意儿在项目简单情况下有什么鸟用... wha ...
- 【洛谷P3884 [JLOI2009]】二叉树问题
题目描述 如下图所示的一棵二叉树的深度.宽度及结点间距离分别为: 深度:4 宽度:4(同一层最多结点个数) 结点间距离: ⑧→⑥为8 (3×2+2=8) ⑥→⑦为3 (1×2+1=3) 注:结点间距离 ...
- zabbix user parameters和Loadable modules的使用方法介绍
目录 需求 实现 原理 前端配置 后端配置 shell实现 python实现 C实现 需求: 采集主机的-/+ buffers/cache free的数据 实现: 采集/proc/meminfo中的 ...
- 游程编码(Run Length Code)
一.什么是游程编码 游程编码是一种比较简单的压缩算法,其基本思想是将重复且连续出现多次的字符使用(连续出现次数,某个字符)来描述. 比如一个字符串: AAAAABBBBCCC 使用游程编码可以将其描述 ...