接口自动化(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管理用例

保证先跑注册再跑登录

运行:



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

相关推荐
DevOps老兵1 小时前
AI Infra实战11:模型部署Pipeline——CI/CD自动化
人工智能·ci/cd·ai·自动化·gitlab
志栋智能2 小时前
安全超自动化:实现安全策略动态调整的保障
网络·安全·自动化
User_芊芊君子3 小时前
让异构增量同步飞起来-KFS全链路并行同步方案
运维·自动化·ansible
海宇AI3 小时前
零信任架构实战:基于海宇风控黑名单构建自动化企业信贷网关
运维·人工智能·架构·自动化
SL-staff4 小时前
规则引擎如何实现风控报告的自动化?JVS-Rules提供解决方案
大数据·自动化·excel·规则引擎·jvs-rules·风控报告·数据溯源
天空属于哈夫克34 小时前
企业微信开发:如何处理接口返回的异常数据?
机器人·自动化·企业微信
大模型码小白4 小时前
【AI大模型】DeepSeek Harness 深度解析:大模型评测框架的架构与实践
java·运维·人工智能·spring·架构·自动化
天远Date Lab5 小时前
零信任架构实战:基于天远行驶OCR证识别构建自动化高并发物流车队准入网关
人工智能·架构·自动化·ocr