【Java自动化学习】接口自动化

一、接口定义

接口(Interface)是一种约定俗成的规范。可以简单的理解就是一个地址,通过地址能访问到数据。能够进行前后台数据交互。

二、接口组成

接口类型包括两种:

1、程序内部的接口(自己开发写的接口)

2、系统对外的接口(引用第三方的接口)

为什么要做接口测试?

答:1) 越底层发现bug,它的修复成本是越低的   --前端(页面/数据)  调用接口(需要时间的)  后端(接口)
2) 前端随便变,接口测好了,后端不用变。 --提高测试效率
3)检查系统的安全性、稳定性,前端传参不可信支付-前端 (金额<0) 直接跳过页面 直接通过传参的方式解决
4)项目-复杂度(业务需求越来越多),传统的测试方法成本急剧增加且测试效率大幅下降,接口测试可以提供这种情况下的解决方案。
5)工具-自动化。接口工具+持续集成工具=自动化   --效率、易用性
接口测试相对容易实现自动化持续集成,且相对UI自动化也比较稳定,可以减少人工回归测试人力成本与时间,缩短测试周期

Http协议数据见此篇文章:Http协议详解

如何进行接口测试?(针对HTTP协议较多)

工具:postmanjmeterapipostapifox
代码:   一般来讲通过代码:java+httpclientpython+requests等,框架和UI自动化差不多,发送请求用断言来判断

三、接口自动化库

在 Java 接口自动化测试中,最常用的库:

1、RestAssured

2、HttpClient

3、OkHttp

3.1  RestAssured

优点:

  • 测试代码简洁明了:可以编写简单、易于理解的测试代码,避免了手动发送请求和处理响应的繁琐步骤。
  • 支持多种数据格式:支持多种数据格式(如SON、XML等),方便进行数据交互测试。
  • 内置断言功能:内置了许多断言方法,可以方便地对响应进行校验,并输出清晰的错误信息
  • 可扩展性强:可以通过插件来扩展功能,比如可以添加lackson或Gson插件来支持更多的数据转换格式

缺点:

  • 有一定学习成本:语法和使用方式与传统java测试框架(如JUnit、TestNG)有些不同,需要一定学习成本
  • 对于复杂场景可能不够灵活:虽然Rest-Assured支持多种数据格式和断言方法,但在处理特殊场景时可能需要编写更多的自定义代码。

示例代码:

public class RestAssurehttpPostTest {
    public static void main(String[] args) throws IOException {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("username", "15096264111");
        requestParams.put("password", "123456");
        requestParams.put("nickname", "小白");
        requestParams.put("sex", "男");
        requestParams.put("img",
            "http://www.baidu.com/static/img/avatar.jpg");
        requestParams.put("company", "null");
        requestParams.put("money", "1000");
        given().contentType("application/x-www-form-urlencoded;charset=UTF-8")
                .formParams(requestParams)
                .when()
                .post("http://www.baidu.com/v1/user/manager/customer")
                .then()
                .statusCode(200)
                .body("msg",equalTo("success"));
    }
}

3.2 HttpClient

优点:

  • 简单易用:HttpClientAPI简单易用,使得在Java接口自动化中使用非常方便。
  • 支持多种协议:HttpClient支持多种协议,例如HTTPHTTPS等,适用于不同类型的接口测试。
  • 可以设置超时时间:HttpClient允许你设置超时时间,可以控制接口请求的响应时间。
  • 支持cookies管理:HttpClient支持cookies管理,可以模拟用户登录后的状态进行接口测试。

缺点:

  • 不支持自动化参数化:HttpClient并不支持自动化参数化,需要自己编写代码实现参数化。
  • URL编码要求高:HttpClientURL编码要求相对较高,因此需要开发人员了解相关知识才能正确使用。
  • 需要手动解析JSON/XML格式:HttpClient可以获取接口返回数据,但需要手动解析JSON/XML格式。
  • 不支持图形界面:HttpClient只能通过编写代码来进行接口测试,不支持图形化界面,对初学者来说可能会有一定的难度。

3.3 OkHttp

优点:

  • OkHttp客户端易于使用,具有良好的文档支持。
  • 它支持多种协议,如HTTP/1.1HTTP/2WebSocket等,可满足不同场景下的需要。
  • 它提供了异步请求和响应,可以提高性能和效率。
  • 发送和接收数据时,OkHttpClient提供了丰富的API,可以自定义请求头、响应头及请求体等。
  • 通过添加拦截器,可以方便地对请求和响应做一些额外的处理,比如记录日志、添加认证等功能。

缺点:

  • 对于一些较为复杂的接口场景,需要编写更多的代码来实现功能。
  • 在处理大量并发请求时,需要谨慎设计线程池和连接池参数,否则可能会影响系统性能。

示例代码:

public class okhttpPostTest {
    public static void main(string[] args)throws IOException
        OkHttpClient client =new OkHttpClient();
                // 构造请求参数
        RequestBody requestBody=new FormBody.Builder("15096264111")
                      .add("username","1255423")
                        .add("password","12345")
                        .add("name","小白")
                        .add("sex","女")
                       .add("img","http://www.baidu.com/static/img/avatar.jpg")
                        .add("company","null")
                        .add("money","1000")
                        .build();

                // 构造请求
             Request request=new Request.Builder()
                    .url("http://www.baidu.com/v1/user/manager/customer")
                    .post(requestBody)
                    .build();
                    //发送请求,并获取响应


                Response response = client.newCall(request).execute();
                String result = response.body().string();
                System.out.println(result);
            
                // 解析 JSON 响应
            ObjectMapper mapper = new ObjectMapper();
            JsonNode jsonNode = mapper.readTree(result);
            String msg = jsonNode.get("msg").asText();
            System.out.println(msg);
                // 断言响应结果
            if (msg.contains("success")) {
                  System.out.println("测试成功");
            } else {
                    System.out.println("测试失败");
            }
                // 关闭响应和 HttpClient
                response.close();
                client.clone();
       }
}
        OkHttpClient是一个较新的库,同时也更加灵活,可定制化程度更高,与 HttpClient 相比, OkHttp 具有更加简洁的API 和高性能,特别是在并发场景下表现更为出色。此外, OkHttp 同样支持 HTTP/HTTPS 协议、请求头设置、 响应解析等功能,并且支持异步调用,因此在接口测试中也是一种非常优秀的选择。

四、OkHttpClient语法格式

导入依赖包:

<!--OkHttpClient需要添加以下依赖-->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.9.0</version>
</dependency>

基本语法步骤:

OkHttp发送Get请求

package com.xuzhongfa.api;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

// 发送get请求
public class GetDemo {
    public static void main(String[] args) throws IOException {
        // 创建发送请求对象
        OkHttpClient client = new OkHttpClient();

        // 创建请求数据 -request
        Request request = new Request.Builder()
                .url("https://www.baidu.com")
                .build();

        // 发送请求
       Response response =  client.newCall(request).execute();

       // 打印响应数据
        if(response.isSuccessful()){
            System.out.println("返回结果是: "+ response.body().string()); // 注意此处不是toString()
        }

        // 关闭请求
        response.close();
    }
}

 运行结果如下:

OkHttp发送Post请求

Post请求参数在body中,请求类型有如下方式:

                                                                        Conetent-type 与 body 对应关系表

(1)Form表单形式

package com.xuzhongfa.api;

import okhttp3.*;

import java.io.IOException;

// 发送post请求-表单
public class PostDemo {
    public static void main(String[] args) throws IOException {
        // 创建发送请求对象
        OkHttpClient client = new OkHttpClient();

        // 创建 post 请求参数body
        RequestBody requestBody = new FormBody.Builder()
                .add("phone","hami")
                .add("password","123456")
                .build();

        //创建请求数据 -request
        Request request = new Request.Builder()
                .url("http://logistics.hctestedu.com/v1/user/customer/login")
                .post(requestBody) // 添加post请求的数据
                .build();

        // 发送请求数据
        Response response = client.newCall(request).execute();
        // 打印响应数据
        if(response.isSuccessful()){
            System.out.println("响应数据是: " + response.body().string());
        }
        // 关闭请求
        response.close();
    }
}

Postman 接口截图如下:

 (2)Json请求方式

1、将请求体中的参数以 Json 字符串的形式进行传递,使用的是 OkHttp 中的 RequestBody 类来构造请求体。首先,需要 将Json字符串解析为MediaType常量类型,即"application/json";然后使用 RequestBody.create()方法将其转换为请求体。
2、注意:使用Json 格式提交方式时,需要服务器端能够正确解析 Json 格式的请求体,并按照要求进行处理。同时,如果目标api 要求请求头部中携带某些特定信息,则需要在 Request.Builder 中添加相应的请求头字段。
package com.xuzhongfa.api;

import okhttp3.*;

import java.io.IOException;

// 通过Post来发送 Json 数据
public class PostJson {
    public static void main(String[] args) throws IOException {
        // 创建 发送请求对象
        OkHttpClient client  = new OkHttpClient();

        // 创建 post 请求参数body
        String data = "{\"goods_id\":11,\"stock\":200}"; // Json数据
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"),data);  // (数据格式,数据)


        //创建请求数据 -request -url
        Request request = new Request.Builder()
                .url("http://shop-xo.hctestedu.com/index.php?s=/api/cart/save&application=app&application_client_type=weixin&token=e7d00b1934ef2db560071aba07d47b4d")
                .post(requestBody) // 添加post请求的数据
                .build();

        // 发送请求数据
        Response response = client.newCall(request).execute();
        // 打印响应数据
        if(response.isSuccessful()){
            System.out.println("响应数据是: " + response.body().string());
        }
        // 关闭请求
        response.close();
    }
}

此处Json数据格式与form表单不一致写法,注意区别 

(3)文件上传形式

package com.xuzhongfa.api;

import okhttp3.*;

import java.io.File;
import java.io.IOException;

// 通过Post来上传文件  -form-data 表单形式上传文件
public class PostFile {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        // 构造请求参数 -文件
        File filepath =  new File("E:\\333.jpg");
        // 文件格式
        MediaType mediaType = MediaType.parse("image/jpeg");
        // 创建参数Body
        RequestBody requestBody =  new MultipartBody.Builder().setType(MultipartBody.FORM)
                //.addFormDataPart("表单数据项名称","文件名",RequestBody.create(文件地址,文件格式))
                .addFormDataPart("file","upFile",RequestBody.create(filepath,mediaType)) 
                .build();

        //创建请求参数request -url
        Request request = new Request.Builder()
                .url("http://httpbin.org/post")
                .post(requestBody)
                .build();

        // 发送请求数据
        Response response = client.newCall(request).execute();
        // 打印响应数据
        if(response.isSuccessful()){
            System.out.println("响应数据是: " + response.body().string());
        }
        // 关闭请求
        response.close();
    }
}

总结:Post请求的形式不同,参数body也会不同

OkHttp发送delete请求

package com.xuzhongfa.api;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

// 发送 删除请求方法
public class DeleteDemo {
    public static void main(String[] args) throws IOException {
        // 创建请求对象
        OkHttpClient client = new OkHttpClient();
        // 请求数据 -request-url
        Request request = new Request.Builder()
                .url("http://logistics.hctestedu.com/v1/fleet/driver/589")
                .delete()
                .build();
        // 发送请求
       Response response =  client.newCall(request).execute();
       // 打印响应数据
        if (response.isSuccessful()){
            String str = response.body().string();
            System.out.println("返回结果是: "+ str);
        }
        // 关闭请求
        response.close();
    }
}

OkHttp发送put请求

在Http协议中,put请求方法指用来对数据body进行修改操作。

使用form表单的方式来进行修改body数据

package com.xuzhongfa.api;

import okhttp3.*;

import java.io.IOException;

// put 请求方法
public class PutDemo {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();
        
        // 修改body参数字段,建议包含全部的字段
        RequestBody requestBody = new FormBody.Builder()
                .add("id","171")
                .add("name","小红")
                .add("sex","女")
               .add("phone","1589457")
               .add("password","123458")
                .add("bank_addr","null")
               .add("bank_number","null")
                .add("is_sms","false")
              .add("idcard","null")
                .add("email","null")
                .add("remark","null")
               .add("driver_license_visible","false")
              .add("token","122922e1a89304e4")
                .build();

        //创建请求数据 -request -url
        Request request = new Request.Builder()
                .url("http://logistics.hctestedu.com/v1/fleet/driver/171")
                .put(requestBody)
                .build();
       Response response =  client.newCall(request).execute();
       // 打印响应内容
        if(response.isSuccessful()){
             String s = response.body().string();
            System.out.println("响应内容为:"+s);
        }
        response.close();
    }
}

五、断言

        在lava接口自动化中,使用OkHttp发送HTTP请求后,可以通过获取响应的状态码、响应头信息以及响应体数据来进行断言。

 一般情况下,我们会先将响应体数据转换成字符串或Json对象,然后对其中的某些字段或属性进行断言

Json提取

        在Java中,可以使用JSON库(如JacksonGson)来解析这个JSON数据,并提取所需数据。这里主要是以Jackson来使用提取Json数据。

导入Jackson依赖

<!--添加ObjectMapper依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.5</version>
</dependency>

准备Json数据

{
    "name":"小红",
    "age":"16",
    "msg":{
        "sex":"女",
        "hobbies":["游泳","跳舞","唱歌"]
    }
}

 解析Json数据来得到name和hobbies信息

package com.xuzhongfa.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonDemo {
    public static void main(String[] args) throws JsonProcessingException {
        String jsonData = "{\n" +
                "    \"name\":\"小红\",\n" +
                "    \"age\":\"16\",\n" +
                "    \"msg\":{\n" +
                "        \"sex\":\"女\",\n" +
                "        \"hobbies\":[\"游泳\",\"跳舞\",\"唱歌\"]\n" +
                "    }\n" +
                "}";

        // 创建获取json数据的objectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        // 解析 Json 数据
       JsonNode jsonNode =  objectMapper.readTree(jsonData);

       // 获取年龄和爱好
        String age = jsonNode.get("age").asText(); // asText() 为转化为文本
        System.out.println("年龄为:" + age);

        JsonNode hobbit = jsonNode.get("msg").get("hobbies"); // 两层需要依次获取
        for(JsonNode s : hobbit){
            System.out.println("爱好为:" + s.asText());
        }
    }
}

断言

断言其实就是将返回的响应数据body(格式为Json)读取,然后进行需要验证的信息进行判断

六、Cookie SessionToken的概念

cookie与seesion的区别见此文章:cookie与session区别

cookie、session、token的详细解答见下篇文章:cookjie\session\token 详解

Token定义

Token的定义:访问令牌 access token, 用于接口中,用于标识接口调用者的身份、凭证。简单来说就是不要需要重复登录。
Token类型:
  • APIToken(接口令牌):用于访问不需要登录的接口
  • USER Token(用户令牌):用于访问需要用户登录之后的接口
  • Token的实效性:token可以是一次性的、也可以在一段时间范围内是有效的
  • Token一般放在请求头headers或者body参数里面。一般在接口文档会有说明
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
  • 客户端使用用户名跟密码请求登录
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  • 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  • 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值