目录
接口本质

HTTP接口

TestNG

快速开始

XML
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.11</version>
<scope>test</scope> //限制只在test目录下使用
</dependency>

在IDEA中运行需要先创建一个类,为这个类创建测试类


运行:

java
package com.jianglin.testngDemo;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class Demo1Test {
@BeforeMethod
public void setUp() {
}
@Test
public void test() {
System.out.println("test...");
}
@AfterMethod
public void tearDown() {
}
}
断言
断言实际值为false,实际值为true的结果
运行之后会显示测试失败并报异常,说明断言成功:

注解属性

第一个dependsOnMethods表示运行test之前先运行test2

第二个alwaysRun = true时表示即使依赖的方法中有错误,本test还是会执行
我们先不添加这个属性,在test2中添加我们刚才断言为false的语句,进行运行:

添加这个属性:

运行之后会发现即便test2有错误,test还是会继续执行:

description为描述,是给我们自己看的,无任何输出变化


第四个enabled = false表示该方法失效,运行不了

java
package com.jianglin.testngDemo;
import org.testng.Assert;
import org.testng.TestRunner;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class Demo1Test {
@BeforeMethod
public void setUp() {
}
@Test(dependsOnMethods = "test2", alwaysRun = true,description = "test")
public void test() {
System.out.println("test...");
// Assert.assertEquals(false, true);
}
@Test
public void test2() {
System.out.println("test2...");
// Assert.assertEquals(false, true);
}
@Test(enabled = false)
public void test3() {
System.out.println("test3...");
}
@AfterMethod
public void tearDown() {
}
}
testNG.xml

再创建三个新的测试类




新建testNG.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<suite name="XXX项目" parallel="false">
<test name="XX模块1">
<classes>
<class name="com.jianglin.testngDemo.Demo1Test" />
<class name="com.jianglin.testngDemo.Demo2Test" />
</classes>
</test> <!-- Test -->
<test name="XX模块2">
<classes>
<class name="com.jianglin.testngDemo.Demo3Test" />
<class name="com.jianglin.testngDemo.Demo4Test" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
运行:


Before/After注解

修改Demo3Test中内容:

Demo4Test内容:

修改testNG.xml内容:

XML
<?xml version="1.0" encoding="UTF-8"?>
<suite name="XXX项目" parallel="false">
<test name="XX模块1">
<classes>
<class name="com.jianglin.testngDemo.Demo3Test" />
<class name="com.jianglin.testngDemo.Demo4Test" />
</classes>
</test>
</suite>
在Demo3Test中加入:


java
package com.jianglin.testngDemo;
import org.testng.annotations.*;
import static org.testng.Assert.*;
public class Demo3Test {
@BeforeSuite//在测试开始之前
public void beforeSuite() {
System.out.println("@BeforeSuite...");
}
@AfterSuite//在测试开始之后
public void afterSuite() {
System.out.println("@AfterSuite...");
}
@BeforeTest//在测试方法之前运行
public void beforeTest() {
System.out.println("@BeforeTest...");
}
@AfterTest//在测试方法之后运行
public void afterTest() {
System.out.println("@AfterTest...");
}
@BeforeClass//在调用的当前类中第一个测试方法之前运行
public void beforeClass() {
System.out.println("@BeforeClass...");
}
@AfterClass//在调用的当前类中所有测试方法之后运行
public void afterClass() {
System.out.println("@AfterClass...");
}
@BeforeMethod//在调用的当前类中所有测试方法之前运行
public void beforeMethod() {
System.out.println("@BeforeMethod...");
}
@AfterMethod//在调用的当前类中所有测试方法之后运行
public void afterMethod() {
System.out.println("@AfterMethod...");
}
@Test
public void test1() {
System.out.println("Demo3...test1...");
}
@Test
public void test2() {
System.out.println("Demo3...test1...");
}
}
运行:

通过观察运行结果可以发现,@BeforeClass、@AfterClass、@BeforeMethod、@AfterMethod都是只在调用的本类中有效,其它类无效。
TestNG传递参数
我们能通过Parameters注解和DataProvider注解来给测试方法传递参数。
Parameters注解
新建testng.xml文件
XML
<?xml version="1.0" encoding="UTF-8"?>
<suite name="XXX项目" parallel="false">
<test name="XX模块1">
<parameter name="firstName" value="Jiang" />
<parameter name="lastName" value="lin" />
<classes>
<class name="com.jianglin.testngDemo.Demo5Test" />
</classes>
</test>
</suite> <!-- Suite -->
新建Demo5Test:
若我们的方法需要参数:

我们什么也不配置的话,运行报错:

添加@Parameters注解实现传参:

testng.xml设置传入参数的值:

运行时要通过testng.xml文件运行,直接运行的话会找不到值

这种方法传参在参数很多或者需要手动输入的时候,很不方便
DataProvider注解
新建Demo6Test:

java
package com.jianglin.testngDemo;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class Demo6Test {
@Test(dataProvider = "datas") //表示test1要调用datas中的值,由于我们这里是个二维数组,且里面有两组数值,故test会执行两次
public void test1(String str1, String str2) {
System.out.println("Demo6...test1...");
System.out.println(str1+" "+str2);
}
@DataProvider(name = "datas") //设置二维数组的名称为datas
public Object[][] datas(){
Object[][] datas = {
{"jiang1","lin1"},
{"jiang2","lin2"},
};
return datas;
}
}
运行:

OKHttp框架
入门

java
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OKHttpDemo {
public static void main(String[] args) throws Exception {
String url = "http://test.lemonban.com/ningmengban/app/login/login.html";
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、构建request
Request request = new Request.Builder()
.url(url)
.get()
.build();
//3、使用client发送请求,返回一个响应
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.headers());
System.out.println(response.body().string());
}
}
发送post请求

java
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class OKHttpDemo2 {
public static void main(String[] args) throws Exception {
String url = "http://test.lemonban.com/ningmengban/mvc/user/login.json";
//1、创建okhttpClient对象
OkHttpClient client = new OkHttpClient();
//2、创建RequestBody
MediaType type = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(type, "username=13212312312&password=123123");
Request request = new Request.Builder().url(url).post(body).build();
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.headers());
System.out.println(response.body().string());
}
}
实战

创建常量类
便于后期维护和修改

java
package com.lemon.constants;
public class Constants {
public static final String BASE_URL = "http://localhost:8080";
public static final String REGISTER_URL = BASE_URL + "/user/register";
public static final String LOGIN_URL = BASE_URL + "/user/login";
public static final String METHOD = "get";
}
工具类编写
get请求

java
package com.lemon.utils;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpUtils {
public static void get(String url,String params) {
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、创建Request
Request request = new Request.Builder().
url(url + "?" + params)
.get()
.build();
//3、使用client发送请求
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
}
post请求

java
package com.lemon.utils;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpUtils {
public static void get(String url,String params) {
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、创建Request
Request request = new Request.Builder().
url(url + "?" + params)
.get()
.build();
//3、使用client发送请求
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String post(String url,String params) {
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、创建RequestBody
MediaType type = MediaType.parse("application/x-www-form-urlencode");
RequestBody requestBody = RequestBody.create(type, params);
//3、创建Request
Request request = new Request.Builder().
url(url)
.post(requestBody)
.build();
//4、使用client发送请求
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.headers());
String body = response.body().string();
System.out.println(body);
return body;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
call方法
这个方法根据传入的请求方式(get/post),自动调用对应的 get 或 post 方法发送请求并返回响应结果,实现请求方式的统一入口。
java
package com.lemon.utils;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpUtils {
public static void get(String url,String params) {
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、创建Request
Request request = new Request.Builder().
url(url + "?" + params)
.get()
.build();
//3、使用client发送请求
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String post(String url,String params) {
//1、创建okHttpClient
OkHttpClient client = new OkHttpClient();
//2、创建RequestBody
MediaType type = MediaType.parse("application/x-www-form-urlencode");
RequestBody requestBody = RequestBody.create(type, params);
//3、创建Request
Request request = new Request.Builder().
url(url)
.post(requestBody)
.build();
//4、使用client发送请求
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.headers());
String body = response.body().string();
System.out.println(body);
return body;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String call(String method,String url,String params) {
if("get".equalsIgnoreCase(method)) {
return get(url, params);
}else if("post".equalsIgnoreCase(method)) {
return post(url, params);
}
return null;
}
}
注册接口测试

新建注册用例类:

java
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
// 自定义常量类
import com.lemon.constants.Constants;
// 自定义HTTP工具类
import com.lemon.utils.HttpUtils;
public class RegisterCase {
@Test(dataProvider = "datas")
public void testRegister(String params) {
String url = Constants.REGISTER_URL;
String method = Constants.METHOD;
String body = HttpUtils.call(method, url, params);
}
@DataProvider(name = "datas")
public Object[][] datas() {
Object[][] datas = {
{"mobilephone=&pwd=333"},
{"mobilephone=13212312312&pwd="},
{"mobilephone=132aaaa&pwd=123456"},
{"mobilephone=13212312312&pwd=33"},
{"mobilephone=13212312399&pwd=123456"},
{"mobilephone=13212312399&pwd=123456"}
};
return datas;
}
}
运行:
实现接口的批量测试

新建登录测试类


java
// 导入TestNG的测试注解和数据提供者注解
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
// 导入自定义常量类
import com.lemon.constants.Constants;
// 导入自定义HTTP工具类
import com.lemon.utils.HttpUtils;
public class LoginCase {
@Test(dataProvider = "datas")
public void testLogin(String params) {
String url = Constants.LOGIN_URL;
String method = Constants.METHOD;
String body = HttpUtils.call(method, url, params);
}
@DataProvider(name="datas")
public Object[][] datas() {
Object[][] datas = {
{"mobilephone=&pwd=333"},
{"mobilephone=13212312312&pwd="},
{"mobilephone=132aaaa&pwd=123456"},
{"mobilephone=13212312312&pwd=33"},
{"mobilephone=13212312312&pwd=33333333"},
{"mobilephone=13212312312&pwd=123456"}
};
return datas;
}
}
运行:

接口断言
在登录测试中增加断言判断:

运行之后:


在注册测试中增加断言判断:

运行:


xml管理用例
保证先跑注册再跑登录

运行:

本期内容先更到这里,接下来可看后续博客。