• 项目地址
    • 原博主代码托管在github,由于国内墙的问题github链接并不稳定,学习过程中备份了一份在自己的gitee上,下面提供地址。觉得项目不错的,可以在原博主的git上点个star,

https://gitee.com/shihu1/lyntest-server

DB表结构设计

  1. CREATE TABLE `api_http_case` (
  2. `id` int(4) NOT NULL AUTO_INCREMENT,
  3. `creator_name` varchar(8) NOT NULL COMMENT '创建人',
  4. `creator_code` varchar(8) NOT NULL COMMENT '创建人code',
  5. `create_date` date NOT NULL COMMENT '创建日期',
  6. `updater_name` varchar(8) DEFAULT NULL COMMENT '更新人',
  7. `updater_code` varchar(8) DEFAULT NULL COMMENT '更新人code',
  8. `update_date` date DEFAULT NULL COMMENT '更新日期',
  9. `category` varchar(16) DEFAULT NULL COMMENT '所属系统名称',
  10. `case_name` varchar(32) NOT NULL COMMENT '接口名称',
  11. `api_url` text NOT NULL COMMENT '接口url',
  12. `api_method` varchar(8) NOT NULL COMMENT '请求方式',
  13. `description` varchar(256) DEFAULT NULL COMMENT '备注',
  14. `header_value` text COMMENT '请求头',
  15. `body_type` int(2) NOT NULL DEFAULT '1' COMMENT 'body类型:1.json 2.urlform',
  16. `body_value` text COMMENT 'body值',
  17. `variable_list` text COMMENT '需要保存的变量',
  18. `expected_list` text COMMENT '需要校验的参数',
  19. PRIMARY KEY (`id`) USING BTREE
  20. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

image.png

实体类封装

  • 思考 一个完整的请求通过java去实现需要哪几种实体类。

    • case 实体类
      • 用来封装用例请求数据 ,从db中捞取数据。
    • response 实体类
      • 用来接收返回数据。

        Case 实体类封装

  • 该项目没有采用常见的 domain/pojo 方式去针对实体类命名,而是统一使用了 xxxDTO 的命名规范来表明与数据库交互的实体类 ```java package com.lyn.dto.autotest;

import com.lyn.bo.ExpectedBO; import com.lyn.bo.HeadersBO; import com.lyn.bo.VariableSaveBO; import lombok.Data; import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotBlank; import java.util.List;

/**

  • @author 简单随风
  • @date 2020/9/8 */ @Data public class HttpCaseDTO {

    private Integer id;

    /**

    • 创建人 */ private String creatorName;

      /**

    • 分组 */ private String category;

      /**

    • 接口名称 */ @Length(min = 1,max = 32,message = “{autotest.http-case.case-name.max}”) @NotBlank(message = “{autotest.http-case.case-name.not-blank}”) private String caseName;

      /**

    • 接口url */ @NotBlank(message = “{autotest.http-case.url.not-blank}”) private String apiUrl;

      /**

    • 请求方式 */ @NotBlank private String apiMethod;

      /**

    • 备注 */ private String description;

      /**

    • 请求头 */ private List headerForm;

      /**

    • body类型:1.json 2.urlform */ private Integer bodyType;

      /**

    • body值 */ private String bodyValue;

      /**

    • 需要保存的变量 */ private List variableList;

      /**

    • 需要校验的参数 */ private List expectedList; }
<a name="AtcKJ"></a>
## Response 实体类封装

- 响应体的实体类,因为非DB相关。  在项目中命名为bo 推测为 business object的缩写
```java
package com.lyn.bo;

import lombok.Data;
import okhttp3.Response;

/**
 * @author 简单随风
 * @date 2020/9/11
 */
@Data
public class ResponseBO {

    private Boolean success;

    private Response response;

    private String msg;

    public ResponseBO(Boolean success, Response response, String msg){
        this.response = response;
        this.success = success;
        this.msg = msg;
    }

    public static ResponseBO success(Response response) {
        return new ResponseBO(Boolean.TRUE, response, null);
    }

    public static ResponseBO failure(String msg) {
        return new ResponseBO(Boolean.FALSE, null, msg);
    }

}

工具类封装

  • 进入到发送请求核心工具类的封装,该框架使用的http请求为 okHttp 来进行接口请求,但是这个框架是否可以适应多协议的接口还有待研究学习,下面附上该项目中 对于请求工具类的封装代码,以及思路学习 memo。
  • 有关okHttp3 的学习 这里不进行过多的赘述,下面贴一个链接可以大致看个入门,方便理解后续代码。

https://www.jianshu.com/p/da4a806e599b

@Slf4j
@Component
public class ApiRequest {

  //1  实力化 okHttpClient 对象
    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(AutoTestConfig.connectTimeout, TimeUnit.SECONDS)
            .writeTimeout(AutoTestConfig.writeTimeout,TimeUnit.SECONDS)
            .readTimeout(AutoTestConfig.readTimeout, TimeUnit.SECONDS)
            .build();

    /**
     *
     * @param httpCaseDTO 传入完整的case数据
     * @return Response返回结果
     */
    public ResponseBO doHttpRequest(HttpCaseDTO httpCaseDTO){

        String url = httpCaseDTO.getApiUrl();

        // 请求方式: POST/GET
        String apiMethod = httpCaseDTO.getApiMethod();

        //2构造 request对象
        Request.Builder builder = new Request.Builder();

        // 设置header
        List<HeadersBO> headersList = httpCaseDTO.getHeaderForm();
        for (HeadersBO headers:headersList){
            if (headers.getEnable()){
                if (StringUtils.isEmpty(headers.getHeaderKey()) || StringUtils.isEmpty(headers.getHeaderValue())){
                    continue;
                }
                builder.header(headers.getHeaderKey(), headers.getHeaderValue());
            }
        }

        // 请求类型:1.json  2.url form
        Integer bodyType = httpCaseDTO.getBodyType();
        String mediaTypeValue = "";

        // 设置body、mediaType
        String body = httpCaseDTO.getBodyValue();
        log.info("请求入参为:" + body);

        // 设置请求content-type
        if (bodyType == 1){
            mediaTypeValue = "application/json;charset=UTF-8";
        } else if (bodyType == 2){
            mediaTypeValue = "application/x-www-form-urlencoded;charset=utf-8";
        }

        Request request = null;
        if ("POST".equals(apiMethod)){
            RequestBody requestBody =RequestBody.create(MediaType.parse(mediaTypeValue), body);
            request = builder.url(url).post(requestBody).build();
        } else if("GET".equals(apiMethod)){
            request = builder.url(url).get().build();
        }

        Response response = null;
        try {
          // 通过前两步中的对象构建 call对象,之后使用execute()方法进行同步请求
          // 使用 okhttp的同步方式提交get请求 
            response = client.newCall(request).execute();
        } catch (Exception e) {
            return ResponseBO.failure(e.toString());
        }

        return ResponseBO.success(response);

    }

UI设计

  • 前端页面较为整洁

image.png
image.png

  • 其针对单个用例的执行入口存放在编辑按钮点击之后的弹出菜单中,观察url可以发现 路径指向为 autotest/http ,进入前端代码工程体中寻找对应view文件

image.png

  • 接着在该view文件中查找请求关键字,找到对应方法 点击进去

image.png

  • image.png
  • image.png
  • 最终查到请求地址为 autotest/http/execute

    接口设计

  • 根据上面得到的请求路径去追溯接口定义,找到如下图

image.png

  • 接口设计详情解析,未完待续 进行后续分析。