接口自动化测试框架优化

接口自动化测试框架优化

  • 输入信息(model): 输入信息表示接口请求过程中和业务相关的具体数据信息。
  • 接口信息(api)
  • 测试用例(testcase)

Model 的表现形式

  • Model复杂程度
    • 简单(1~2特字段): 使用Model的类型为参数
    • 正常(多个字段): 实体类
    • 非常复杂(多个字段,且嵌套数据较多): yaml、json、excel

JSON 快速转换实体类

  • idea 插件
    • GsonFormatPlus
    • Lombok
<!--            maven 编译使用插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <parameters>true</parameters>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${maven.compiler.encoding}</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <!-- 解决 maven 编译时无法识别 lombok 插件 -->
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.8</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

1730064736075

接口自动化测试-过滤器(filter)

过滤器的使用场景

所有的公共配置

  • 日志信息
  • 请求头信息

过滤器的使用

  • 定义: 实现 Filter 接口,重写 filter 方法(请求信息,响应信息,过滤器信息)
  • 使用: given().filter(重写的filter实例)
  • 实现代码
// 重合公共配置提取
package com.vernon.poppy.filter;

import com.vernon.poppy.service.BaseApiService;
import io.restassured.filter.Filter;
import io.restassured.filter.FilterContext;
import io.restassured.http.Cookie;
import io.restassured.http.Header;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;

import static com.vernon.poppy.util.Log.log;
import static io.qameta.allure.Allure.addAttachment;

public abstract class ApiFilter implements Filter {

    public Header header;

    public Cookie cookie;

    public String uri;

    public ApiFilter(BaseApiService baseApiService) {
        this.header = baseApiService.getHeader();
        this.cookie = baseApiService.getCookie();
        this.uri = baseApiService.getBaseUri();
    }

    @Override
    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {

        return commonFilter(requestSpec, responseSpec, ctx);
    }

    public Response commonFilter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx){

        // 设置请求基地址 等于配置域名或IP
        requestSpec.baseUri(uri);

        if (header != null) {
            // 添加请求头信息
            requestSpec.header(header);
        }

        if (cookie != null) {
            // 添加 Cookies
            requestSpec.cookie(cookie);
        }

        // 日志的配置: 使每个接口在调用过程中,自动打印输出日志信息
        // 1. 获取请求信息
        String requestsInfo = requestSpec.getMethod() + " "
                + requestSpec.getURI()
                + "\n Request Body: \n"
                + requestSpec.getBody();
        // 2. 发起真是请求,获取响应对象
        Response response = ctx.next(requestSpec, responseSpec);
        // 3. 获取响应信息
        String responseInfo = "\n Response Status: "
                + response.getStatusCode() + " "
                + response.getStatusLine()
                + "\n Response Body: "
                + response.getBody().asPrettyString();

        log.debug("接口请求: {}",requestsInfo);
        log.debug("接口响应: {}",responseInfo);
        // 将接口请求和响应日志添加至 allure 报告
        addAttachment("接口请求: ",requestsInfo);
        addAttachment("接口响应: ",responseInfo);

        return response;
    }
}

// 特定场景公共配置提取
package com.vernon.poppy.filter;

import com.vernon.poppy.service.BaseWechatApiService;
import io.restassured.filter.FilterContext;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;

public class WechatFilter extends ApiFilter {

    public String accessToken;

    public WechatFilter(BaseWechatApiService wechatApiService) {
        super(wechatApiService);
        this.accessToken = wechatApiService.getAccessToken();
    }

    @Override
    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {
        // 添加公共请求参数
        requestSpec.queryParam("access_token",accessToken);

        return commonFilter(requestSpec, responseSpec, ctx);
    }
}

// 调用 Filter
public DocumentContext getSimpleList(DepartmentDTO departmentDTO) {
        Response response = given()
                    // 添加公共部分过滤器
                    .filter(filter)
                    .queryParam("id",departmentDTO.getParentId())
                .when()
                    .get(SIMPLE_LIST_URI)
                .then()
                    .statusCode(200)
                    .extract().response();
        return JsonPath.parse(response.getBody().asString());
    }

java: No implementation was created for …代码编译失败问题

java: No implementation was created for AdminUserConverter due to having a problem in the erroneous element java.util.ArrayList. 
Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable 
MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.

  • 出现原因
    新版本idea所使用的java compilier编译器,lombok用不来, 得是 javac

  • 解决
    需要在idea编译器中禁用新版不的编译器,这样就能解决问题
    如下图,在编译器位置加入这句话: -Djps.track.ap.dependencies=false