接口自动化(TestNG+OKHttp)

目录

接口本质

HTTP接口

TestNG

快速开始

断言

注解属性

testNG.xml

Before/After注解

TestNG传递参数

Parameters注解

DataProvider注解

OKHttp框架

入门

发送post请求

实战

创建常量类

工具类编写

get请求

post请求

call方法

注册接口测试

新建登录测试类

接口断言

xml管理用例


接口本质

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管理用例

保证先跑注册再跑登录

运行:



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

相关推荐
阿蔹6 小时前
TestHub智能测试管理平台框架介绍
自动化·接口测试·测试·测试平台
瞬维AI11 小时前
RPA与AI智能体的跨平台自动化执行架构:从任务编排到异常处理
人工智能·自动化·rpa
qq_426003966 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
其实防守也摸鱼6 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
森叶6 天前
用远程调试端口自动化 Chrome 应用商店发布:做法、三个真坑,以及你必须知道的风险
自动化
懂软件的胡子个哥6 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
爱学习的执念6 天前
助力金九银十1000道软件测试面试题(功能、接口、自动化、WEB、APP.......)附答案
软件测试·面试
jingli96 天前
多平台多店铺客服怎么统一接待?千牛/拼多多/抖音/京东/闲鱼/微信/快手切窗口太累,一个后台集中接管的七步落地方案(2026 实操版)
人工智能·自动化·用户运营
坚定信念,勇往无前6 天前
Playwright 的本质
自动化·网络爬虫