接口自动化 - 接口组合业务练习(CRUD组合)-REST-assure(Java版)

文章目录

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。



本文开始

1. 需求分析

接口自动化整体思路构建

1.1 业务需求分析

明确被测产品:petstore系统 - 宠物管理。

宠物商店接口文档:Swagger文档

宠物管理业务场景:

1.添加宠物。

2.查询宠物信息。

3.修改宠物信息。

4.删除宠物。

1.2 编写自动化脚本思路

2. 接口自动化脚本编写

  1. 首先编写CRUD单一接口,保证单一接口跑通,然后考虑业务接口组合优化,和跑通;
  2. 接口逻辑和业务逻辑可以分开

【注】

1.请求中不添加 contentType(ContentType.JSON) 会导致请求失败

2.因为HTTP协议需要明确的Content-Type标头来告诉服务器如何处理请求体。

  • asString() 和 toString() 在RestAssured中有重要区别
    1.asString(): 将HTTP响应体内容作为字符串返回
    如:asString() 返回:{"id": 1, "name": "John"}
    2.toString(): 返回Body对象的字符串表示,通常是对象本身的描述信息
    如:输出类似:io.restassured.internal.RestAssuredResponseImplBody2@1a2b3c4d

编写CRUD基础接口代码-保证每个接口测试通过

java 复制代码
/**
 * 新增-接口方法 POST
 *  url: https://petstore.swagger/pet
 */
public void add() {
	//构造请求体参数
    String newPet = "{\"id\":"+petId+",\"category\":{\"id\":0,\"name\":\"string\"},\"name\":\""+
            newPetName+"\",\"photoUrls\":[\"string\"],\"tags\":[{\"id\":0,\"name\":\"string\"}],\"status\":\"available\"}";
    given()
        .contentType(ContentType.JSON)
        .body(newPet)
        .log().all()
    .when()
        .post(baseURL)
    .then()
        .log().all();
}

/**
 * 新增方法:忽略HTTPS校验
 */
public void add2() {
    String newPet = "{\"id\":"+petId+",\"category\":{\"id\":0,\"name\":\"string\"},\"name\":\""+
            newPetName+"\",\"photoUrls\":[\"string\"],\"tags\":[{\"id\":0,\"name\":\"string\"}],\"status\":\"available\"}";
    given()
        //忽略HTTPS校验
        .relaxedHTTPSValidation()
        .contentType(ContentType.JSON)
        .body(newPet)
        .log().all()
    .when()
        .post(baseURL)
    .then()
        .log().all();
}

/**
 * 查看-接口方法 GET
 *  url: https://petstore.swagger/findByStatus?status=available
 */
public String get() {
    HashMap<String, Object> statusQuery = new HashMap<>();
    statusQuery.put("status", "available");
    String body = given()
        .queryParams(statusQuery)
        .log().all()
    .when()
        .get(baseURL + "/findByStatus")
    .then()
        .log().all()
        .extract().response()
        .getBody().asString();
    System.out.println(body);
    return body;
}

/**
 * 更新-接口方法 PUT
 *  url:  https://petstore.swagger/pet
 */
public void update() {
    String updatePet = "{\"id\":"+petId+",\"category\":{\"id\":0,\"name\":\"string\"},\"name\":\""+
            updatePetName+"\",\"photoUrls\":[\"string\"],\"tags\":[{\"id\":0,\"name\":\"string\"}],\"status\":\"available\"}";
    given()
        .contentType(ContentType.JSON)
        .body(updatePet)
        .log().all()
    .when()
        .post(baseURL)
    .then()
        .log().all();
}

/**
 * 删除-接口方法 DELETE
 *  url: https://petstore.swagger/pet/petId
 *   删除参数是在路径上,直接拼接到url上
 */
public void delete() {
    given()
        .log().all()
    .when()
        .delete(baseURL + "/" + petId)
    .then()
        .log().all();
}

测试用例业务逻辑执行:

java 复制代码
/**
 * 新增宠物测试用例
 *  执行业务逻辑:先新增,再查看验证
 */
@Order(12)
@Test
public void addTest() {
    //新增
    add();
    //查看
    String body = get();
    //校验
    DocumentContext context = JsonPath.parse(body);
    List<Long> ids = context.read("$..id");//或者使用$[*].id
    List<String> names = context.read("$..name");
    List<String> status = context.read("$..status");//$[*].status

//        System.out.println(status);
    assertAll(
        () -> assertThat(status, everyItem(equalTo("available"))),
        () -> assertThat(ids, Matchers.hasItem(Long.valueOf(petId))),
        () -> assertThat(names, Matchers.hasItem(newPetName))
    );
}

/**
 * 修改宠物测试用例
 */
@Order(13)
@Test
public void updateTest() {
    //修改宠物
    update();
    //查看修改
    String body = get();
    //断言
    DocumentContext context = JsonPath.parse(body);
    List<Long> ids = context.read("$..id");//或者使用$[*].id
    List<String> names = context.read("$..name");
    assertAll(
        //验证每一个status,都等于available
        () -> assertThat(ids, Matchers.hasItem(Long.valueOf(petId))),
        () -> assertThat(names, Matchers.hasItem(updatePetName))
    );
}

/**
 * 删除宠物测试用例
 */
@Order(14)
@Test
public void deleteTest() {
    //删除宠物
    delete();
    //查询删除结果
    String body = get();
    //断言
    DocumentContext context = JsonPath.parse(body);
    List<Long> ids = context.read("$..id");//或者使用$[*].id
    assertAll(
        //ids,都不等于petId
        () -> assertThat(ids, not(Matchers.hasItem(Long.valueOf(petId))))
    );

}

断言说明:

assertAll 是JUnit 5的特性,它允许同时执行多个断言,即使前面的断言失败,也会继续执行后面的断言,最后报告所有失败。

java 复制代码
assertAll(
      () -> assertThat(status, everyItem(equalTo("available"))),
      () -> assertThat(ids, Matchers.hasItem(Long.valueOf(petId))),
      () -> assertThat(names, Matchers.hasItem(newPetName))
);

1.检查status列表中的每个元素都等于"available"

everyItem():Hamcrest匹配器,表示"每一个元素"

equalTo("available"):匹配器,表示"等于 available"

2.检查ids列表中是否包含转换后的petId

Long.valueOf(petId):将字符串转换为Long

hasItem():Hamcrest匹配器,表示"包含某个元素"

2.3 优化

提取公共参数

java 复制代码
@BeforeAll
public static void beforeAll() {
     //公共URL提取
     baseURL = "https://petstore.swagger/pet";
     //提取需要提前设置的传递参数,这里简单构造,后续data数据参数化
     petId = "123456123456";
     newPetName = "newPet";
     updatePetName = "updatePet";
     //配置代理地址
//   RestAssured.proxy = host("127.0.0.1").withPort(8888);
 }

配置代理查看接口数据:

出现接口问题,不知道如何处理-使用代理查看接口数据

操作步骤:

1.请求前BeforeAll中:配置代理信息

java 复制代码
RestAssured.proxy = host("127.0.0.1").withPort(8888);

2.given()中忽略https校验:

java 复制代码
given().relaxedHTTPSValidation()

【注】接口发送到服务端前,拦截请求,发送到代理工具上,查看具体信息是否正确,然后再将接口发送到服务端;接口→代理工具→服务端

设置用例排序执行-Junit5配置

用例排序执行步骤:

1.test/resources目录下创建:junit-pltform.properties文件(文件名自定义)

配置如下设置:

yaml 复制代码
junit.jupiter.testmethod.order.default=org.junit.jupiter.api.MethodOrderer$OrderAnnotation

2.在测试用例中使用注释@Order()指定顺序使用即可

数字小的先执行

生成测试Allure报告

文件中导入.allure文件

通过mvn命令生成

mvn clean test -Dtest=测试类路径 allure:report

mvn allure:serve


总结

✨✨✨各位读友,本篇分享到内容是否更好的帮助你理解,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
🎉🎉🎉一遇挫折就灰心丧气的人,永远是个失败者。而一向努力奋斗,坚韧不拔的人会走向成功。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

相关推荐
阿蔹14 小时前
UI测试自动化-Web-Python-Appium
前端·python·ui·appium·自动化
Gofarlic_oms114 小时前
Kisssoft许可证服务器高可用性(HA)集群配置方案
运维·服务器·网络·安全·需求分析·devops
qinyia14 小时前
WisdomSSH解决硬盘直通给飞牛系统时控制器无法绑定的问题
java·linux·服务器
全能打工人14 小时前
ruoyi项目导出PDF
java·elementui·pdf
昵称什么的不存在14 小时前
linux安装WPS和typora等deb包,以及typora的linux版本激活
linux·运维·wps
a努力。14 小时前
哈罗Java后端面试被问:消息队列的选型考量因素
java·面试·linq
网硕互联的小客服14 小时前
服务器平均响应时间和数据包大小有什么关系?
运维·服务器·网络