目录
一、 背景介绍
二、核心概念与联系
2.1 JUnit核心概念
2.2 TestNG核心概念
2.3 JUnit与TestNG的联系
三. 核心算法原理的详细讲解
3.1 JUnit算法原理
3.2 TestNG算法原理
四、什么是TestNG
五、 TestNG配置
2.1 Maven项目的结构:
2.2 POM文件中配置:
2.3 TestNG插件安装:
六、 TestNG使用
3.1 编写测试用例脚本
(1)新建测试用例类(2)使用注解
3.2 单个类的用例
3.3 多个类的用例(Test Suite)
七、HttpClient 框架
7.1 get请求无参
八、思考与总结
一、 背景介绍
JUnit提供了一种简单易用的方法来编写、运行和维护单元测试。TestNG则是一个更高级的单元测试框架,它基于JUnit,但提供了更多的功能和灵活性。TestNG已经被广泛应用于Java项目中,本人主要使用的是TestNG,接下来给大家分享一下Testng的使用方式和操作。
二、核心概念与联系
2.1 JUnit核心概念
测试用例:是一种用于验证代码行为的方法。测试用例应该具有以下特点:独立、可重复、可维护、可读性好。
断言:是用于检查代码行为是否符合预期的语句。例如,assertEqual用于检查两个对象是否相等。
测试套件:是一组相关的测试用例的集合。测试套件可以包含多个测试类,每个测试类可以包含多个测试方法。
2.2 TestNG核心概念
组:是一组相关的测试用例的集合。TestNG中的组可以通过@Test、@Before、@After等注解来定义。
数据驱动:是一种用于自动化测试的方法,它可以通过使用@DataProvider注解来提供测试用例的数据。
参数化:是一种用于实现数据驱动的方法,它可以通过使用@Parameters注解来传递测试用例的参数。
2.3 JUnit与TestNG的联系
JUnit和TestNG都是用于Java单元测试的框架,它们的核心概念和功能有很多相似之处。例如,它们都支持断言、测试套件、测试用例等。但是,TestNG比JUnit更加强大,它提供了更多的功能和灵活性,例如支持组、数据驱动、参数化等。
三. 核心算法原理的详细讲解
3.1 JUnit算法原理
JUnit的核心算法原理是基于测试用例和断言的。具体操作步骤如下:
编写测试用例:测试用例是一种用于验证代码行为的方法。它应该具有以下特点:独立、可重复、可维护、可读性好。
编写断言:断言是用于检查代码行为是否符合预期的语句。例如,assertEqual用于检查两个对象是否相等。
运行测试套件:测试套件是一组相关的测试用例的集合。测试套件可以包含多个测试类,每个测试类可以包含多个测试方法。
3.2 TestNG算法原理
TestNG的核心算法原理是基于组、数据驱动和参数化。具体操作步骤如下:
定义组:组是一组相关的测试用例的集合。TestNG中的组可以通过@Test、@Before、@After等注解来定义。
实现数据驱动:数据驱动是一种用于自动化测试的方法,它可以通过使用@DataProvider注解来提供测试用例的数据。
实现参数化:参数化是一种用于实现数据驱动的方法,它可以通过使用@Parameters注解来传递测试用例的参数。
运行测试套件:测试套件是一组相关的测试用例的集合。测试套件可以包含多个测试类,每个测试类可以包含多个测试方法。
四、什么是TestNG
TestNG是一个开源的自动化测试框架,它受JUnit和NUnit启发,其中“NG”即表示Next Generation,其功能更强大使用更方便,也是目前最流行的测试框架
五、 TestNG配置
2.1 Maven项目的结构:
---pom.xml 核心配置,项目根下
---src
---main
---java java源码目录
---resources java配置文件目录
---test
---java 测试源码目录
---resources 测试配置目录
---target 编译之后的class文件存放路径
2.2 POM文件中配置:
在maven工程的pom.xml文件中加入以下依赖:
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.10</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- testng.xml所在的路径,这里指的是相对路径 -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<version>2.22.1</version>
</plugin>
2.3 TestNG插件安装:
六、 TestNG使用
3.1 编写测试用例脚本
(1)新建测试用例类
(2)使用注解
- @Test注解:使用改注解的方法或类可以被testNG识别并运行
@Test(dependsonMethods="test2"):依赖其他方法,运行当前方法之前需要先执行test2
@Test(alwayRun=true):设置为true时,无论什么情况都会运行
@Test(description="xxx"):对用例进行说明
@Test(enabled=false):设置为false时,表示改方法失效
@Test(dataProvider="datas"):设置数据提供者的名称
- Before/After注解
针对当前项目:
@BeforeSuite:带有该注释的方法将在该套件中的所有测试方法运行之前运行,仅运行一次。
@AfterSuite:带有该注释的方法将在该套件中的所有测试方法运行之后运行,仅运行一次。
@BeforeTest:带有该注释的方法将在运行属于标签<test>内的类的所有测试方法之前执行
@AfterTest:带有该注释的方法将在运行属于标签<test>内的类的所有测试方法之后执行
针对当前类:
@BeforeClass:带有该注释的方法将在调用当前类的第一个测试方法之前执行
@AfterClass:带有该注释的方法将在调用当前类的第一个测试方法之后执行
@BeforMethod:带有该注释的方法将在每个测试方法之前运行
@AfterMethod:带有该注释的方法将在每个测试方法之后运行
@BeforeGroups:此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行。
@AfterGroups:该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行。
- Testng基本注解和执行顺序
@Test // 标识测试方法
@BeforeMethod // 测试方法之前运行
@AfterMethod // 测试方法之后运行
@BeforeClass // 类运行之前运行的方法,调用当前类中的第一个方法之前运行测试用例开始执行一次
@AfterClass // 类运行之后运行的方法,当前类中的所有测试方法运行之后运行,测试用例结束执行一次
import org.testng.annotations.*;
public class BasicAnnotation {
@Test // Alt+回车:快捷键配置testng
public void testCase1(){
System.out.println("Test这是测试用例1111");
}
@Test // @Test标识这是一个测试用例方法
public void testCase2(){
System.out.println("Test这是测试用例2222");
}
@BeforeMethod
public void beforeMethod(){
System.out.println("BeforeMethod这是在测试方法之前运行");
}
@AfterMethod
public void afterMethod(){
System.out.println("AfterMethod这是在测试方法之后运行");
}
@BeforeClass // 测试用例开始执行一次
public void beforeClass(){
System.out.println("beforeClass 这是在类运行之前运行的方法,也就是调用当前类中的第一个方法之前运行");
}
@AfterClass // 测试用例结束执行一次
public void afterClass(){
System.out.println("afterClass 这是在类运行之后运行的方法,当前类中的所有测试方法运行之后运行");
}
@BeforeSuite
public void f1(){
System.out.println("@BeforeSuite套件测试,类运行之前运行之前运行");
}
@AfterSuite
public void f2(){
System.out.println("@AfterSuite套件测试,类运行之后运行之后运行");
}
}
- 执行结果:
@BeforeSuite套件测试,类运行之前运行之前运行
beforeClass 这是在类运行之前运行的方法,也就是调用当前类中的第一个方法之前运行
BeforeMethod这是在测试方法之前运行
Test这是测试用例2222
AfterMethod这是在测试方法之后运行
afterClass 这是在类运行之后运行的方法,当前类中的所有测试方法运行之后运行
@AfterSuite套件测试,类运行之后运行之后运行
- 传递参数
(1)@Parameters
@Parameters({"first","last"}):描述如何将参数传递给@Test方法。
需要预先在testng.xml中使用<parameter>标签传入参数名和参数值
<parameter name="first" value="尼古拉斯"/>
(2)@DataProvider:可以传递更多的参数,不需要在xml中写,直接在方法上加注解就可以用
@DataProvider(name="loginData")
private Object[][] LoginDataProvider() throws IOException {
Object[][] result=null;
SqlSession session=DatabaseUtil.getSqlSession();
result=new Object[][]{{session.selectOne("loginTest",1)},{session.selectOne("loginTest",2)}};
return result;
}
(3)断言方法:
- 硬断言Assert类:断言失败,阻塞后边其他代码执行
- 断言方法基本上是有1至3个输入参数,1个参数为真或假;2-3个参数的顺序是actualValue(实际值)、expectedValue(期望值)、[, message](信息)。
- Assert.assertEquals(actual,Expected):断言,进行实际和预期值的比较
(1)assertTrue:判断是否为True。
(2)assertFalse:判断是否为False。
(3)assertSame:判断引用地址是否相同。
(4)assertNotSame:判断引用地址是否不相同。
(5)assertNull:判断是否为null。
(6)assertNotNull:判断是否不为null。
(7)assertEquals:判断是否相等。
(8)assertNotEquals:判断是否不相等。
(9)assertEqualsNoOrder:判断忽略顺序是否相等。
- 软断言SoftAssert类:断言失败,不阻塞后边其他代码执行
3.2 单个类的用例
打开类文件,空白处右键,Run As ->TestNG Test
和单个用例一样,不同之处只是在类文件里空白处点击右键。执行该类下所有的测试用例。
3.3 多个类的用例(Test Suite)
使用testng.xml文件,该文件用来管理测试用例,并运行testNG。
- <suite>:套件就是将所有的测试类整理在一块,形成一套测试用例
- <test>:测试集是指测试模块,一般一个项目可以按照模块分为几部分,即不同的test
- <classes>:测试集下的所有测试类
- <class>:具体测试类,name 属性指定测试类的路径
- <methods>:测试类下具体的测试方法,如果不写此标签则默认包含测试类下的所有方法。
举例,本文的testng.xml内容如下:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="testng test" parallel="false">
<test name="API test">
<classes>
<class name="com.apitest.APITest"/>
<class name="com.apitest.APITest2"/>
</classes>
</test>
<test name="GUI test">
<classes>
<class name="com.seletest.FirstWebTest"/>
</classes>
</test>
</suite>
注:<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 必须要添加,这是testng.xml文件的规范要求。
七、HttpClient 框架
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Http_Client</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
</dependencies>
</project>
7.1 get请求无参
public class MyHttpClient {
@Test
public void test1() throws IOException {
// 用来请求结果
String result;
String url = "http://www.tpshop.com/index.php?m=Home&c=User&a=verify";
HttpGet get = new HttpGet(url);
// 这个是用来执行那个get方法
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(get);
result = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(result);
}
}
实际工作是基础URl等基本信息放在配置文件中 ==》application.properties
test.url = http://www.tpshop.com
test_url= http://www.litemall360.com:8080
getCookie.url = /index.php?m=Home&c=User&a=verify
login.url = /index.php?m=Home&c=User&a=do_login
login_url = /xxxx/auth/login
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.List;
import java.util.ResourceBundle;
public class MyCookiesForGet {
public String url;
private ResourceBundle bundle;
// 存储cookies信息
private CookieStore store;
@BeforeTest
public void beforeTest(){
bundle = ResourceBundle.getBundle("application");
url = bundle.getString("test.url");
}
@Test
public void testGetCookies() throws IOException {
String result;
// 从配置文件中拼接url
String uri = bundle.getString("getCookie.url");
String testurl = this.url + uri;
HttpGet get_cookies_url = new HttpGet(testurl);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(get_cookies_url);
result = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(result);
// 获取cookies信息
this.store = client.getCookieStore();
List<Cookie> cookieList = store.getCookies();
for (Cookie cookie : cookieList){
String name = cookie.getName();
String value =cookie.getValue();
System.out.println(name + value);
}
}
}
7.2 post请求、表单格式参数、携带cookies
public class MyCookiesForGet {
public String url;
private ResourceBundle bundle;
// 存储cookies信息
private CookieStore store;
@BeforeTest
public void beforeTest(){
bundle = ResourceBundle.getBundle("application", Locale.CANADA);
url = bundle.getString("test.url");
}
@Test
private void testPostMethod() throws IOException {
String uri = bundle.getString("login.url");
// 地址拼接
String testUrl = this.url + uri;
// 声明一个post方法
HttpPost httpPost = new HttpPost(testUrl);
// 添加参数
JSONObject param = new JSONObject();
param.put("username","15788888888");
param.put("password","123456");
param.put("verify_code",888);
// 设置请求头信息、设置headers
httpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
// 将参数添加到方法中
StringEntity entity = new StringEntity(param.toString(),"utf-8");
httpPost.setEntity(entity);
// 声明一个对象来进行响应结果的存储用来进行方法的执行,并设置cookies信息
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(this.store).build();
//执行post的方法并得到响应结果
CloseableHttpResponse response3 = httpclient.execute(httpPost);
//就是判断返回结果是否符合预期
int statusCode = response3.getStatusLine().getStatusCode();
System.out.println("statusCode = "+ statusCode);
String result = EntityUtils.toString(response3.getEntity(),"utf-8");
if (statusCode == 200){
System.out.println(result);
}else {
System.out.println("登陆失败!");
}
// 处理结果,断言是否符合预期
// 将返回的响应结果字符串转化成json对象
JSONObject resultJson = new JSONObject(result);
// 具体的判断返回结果的值
// 获取到结果值
System.out.println(resultJson);
// String success = (String) resultJson.get("errmsg");
// System.out.println(success);
// Assert.assertEquals("成功",success);
}
}
7.3 post请求、json格式参数、携带cookies
public class MyCookiesForPost {
public String url;
private ResourceBundle bundle;
// 存储cookies信息
private CookieStore store;
@BeforeTest
public void beforeTest(){
bundle = ResourceBundle.getBundle("application", Locale.CANADA);
url = bundle.getString("test_url");
}
@Test
private void testPostMethod() throws IOException {
String uri = bundle.getString("login_url");
// 地址拼接
String testUrl = this.url + uri;
// 声明一个post方法
HttpPost httpPost = new HttpPost(testUrl);
// 添加参数
JSONObject param = new JSONObject();
// param.put("username","15708460952");
// param.put("password","123456");
// param.put("verify_code",888);
param.put("username","user123");
param.put("password","user123");
// 设置请求头信息、设置headers
httpPost.setHeader("Content-Type","application/json;charset=UTF-8");
// 将参数添加到方法中
StringEntity entity = new StringEntity(param.toString(),"utf-8");
httpPost.setEntity(entity);
// 声明一个对象来进行响应结果的存储用来进行方法的执行,并设置cookies信息
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(this.store).build();
//执行post的方法并得到响应结果
CloseableHttpResponse response3 = httpclient.execute(httpPost);
//就是判断返回结果是否符合预期
int statusCode = response3.getStatusLine().getStatusCode();
System.out.println("statusCode = "+ statusCode);
String result = EntityUtils.toString(response3.getEntity(),"utf-8");
if (statusCode == 200){
System.out.println(result);
}else {
System.out.println("登陆失败!");
}
// 处理结果,断言是否符合预期
// 将返回的响应结果字符串转化成json对象
JSONObject resultJson = new JSONObject(result);
// 具体的判断返回结果的值
// 获取到结果值
// System.out.println(resultJson);
String success = (String) resultJson.get("errmsg");
System.out.println(success);
Assert.assertEquals("成功",success);
}
}
7.4 处理get请求获取cookies,关联接口post请求携带cookies
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.util.List;
import java.util.ResourceBundle;
public class get_cookies_HttpClient {
public String url;
private ResourceBundle bundle;
// 存储cookies信息
private CookieStore store;
@BeforeTest
public void beforetest(){
bundle = ResourceBundle.getBundle("application");
url = bundle.getString("test.url");
}
@Test
private void testGetCookies1() throws Exception {
String result;
String uri = bundle.getString("getCookie.url");
String testurl = this.url + uri;
HttpGet get_cookies_url = new HttpGet(testurl);
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(get_cookies_url);
result = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(result);
// 获取cookies信息
this.store = client.getCookieStore();
List<Cookie> cookieList = store.getCookies();
for (Cookie cookie : cookieList){
String name = cookie.getName();
String value =cookie.getValue();
System.out.println(name + value);
}
}
@Test
private void testPostMethod2() throws Exception {
String uri2 = bundle.getString("login.url");
// 地址拼接
String testUrl = this.url + uri2;
// 声明一个post方法
HttpPost httpPost = new HttpPost(testUrl);
// 添加参数
JSONObject param = new JSONObject();
param.put("username","15708460952");
param.put("password","123456");
param.put("verify_code",8888);
// 设置请求头信息、设置headers
httpPost.setHeader("Content-Type","application/json;charset=UTF-8");
// 将参数添加到方法中
StringEntity entity = new StringEntity(param.toString(),"utf-8");
httpPost.setEntity(entity);
// 声明一个对象来进行响应结果的存储用来进行方法的执行,并设置cookies信息
System.out.println(this.store);
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(this.store).build();
//执行post的方法并得到响应结果
CloseableHttpResponse response3 = httpclient.execute(httpPost);
//就是判断返回结果是否符合预期
int statusCode = response3.getStatusLine().getStatusCode();
System.out.println("statusCode = "+ statusCode);
String result = EntityUtils.toString(response3.getEntity(),"utf-8");
if (statusCode == 200){
System.out.println(result);
}else {
System.out.println("登陆失败!");
}
// 处理结果,断言是否符合预期
// 将返回的响应结果字符串转化成json对象
JSONObject resultJson = new JSONObject(result);
// 具体的判断返回结果的值
// 获取到结果值
System.out.println(resultJson);
String success = (String) resultJson.get("msg");
System.out.println(success);
Assert.assertEquals("登陆成功",success);
}
}
八、思考与总结
testNG还有很多很强大的机制,例如用例失败重试,需要实现IRetryAnalyzer接口,相比其他参数的使用,其稍微复杂一些,有空了再搞吧
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!