文章目录
- [1. 需求分析](#1. 需求分析)
-
- [1.1 业务需求分析](#1.1 业务需求分析)
- [1.2 编写自动化脚本思路](#1.2 编写自动化脚本思路)
- [2. 接口自动化脚本编写](#2. 接口自动化脚本编写)
-
- 编写CRUD基础接口代码-保证每个接口测试通过
- 测试用例业务逻辑执行:
- 断言说明:
- [2.3 优化](#2.3 优化)
- 总结
✨✨✨学习的道路很枯燥,希望我们能并肩走下来!
编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。

本文开始
1. 需求分析
接口自动化整体思路构建
1.1 业务需求分析
明确被测产品:petstore系统 - 宠物管理。
宠物商店接口文档:Swagger文档
宠物管理业务场景:
1.添加宠物。
2.查询宠物信息。
3.修改宠物信息。
4.删除宠物。
1.2 编写自动化脚本思路
2. 接口自动化脚本编写
- 首先编写CRUD单一接口,保证单一接口跑通,然后考虑业务接口组合优化,和跑通;
- 接口逻辑和业务逻辑可以分开
【注】
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
总结
✨✨✨各位读友,本篇分享到内容是否更好的帮助你理解,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
🎉🎉🎉一遇挫折就灰心丧气的人,永远是个失败者。而一向努力奋斗,坚韧不拔的人会走向成功。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!


