文章目录
- [1. 自动化前准备](#1. 自动化前准备)
- [2. 接口自动化分层](#2. 接口自动化分层)
- 3.接口自动化代码实现
- 优化
- 小技巧
- 总结
✨✨✨学习的道路很枯燥,希望我们能并肩走下来!
编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。

本文开始
1. 自动化前准备
1.需求分析:对自动化前的需求进行详细分析
2.接口测试用例设计
3.编写接口自动化测试脚本
保证单接口自动化通过;再考虑业务流程自动化测试(组合接口测试);
【注】当前利用AI辅助,使用智能体辅助,极大降低自动化代码编写难度;
2. 接口自动化分层
接口自动化框架设计:
封装 + 分层+ 接口实现和测试用例以及断言进行拆分
yaml
├── apis
│ ├── base_api
│ ├── department
│ └── wework
├── config
│ └── config.yaml
├── tests
│ ├── test_departments
│ └── test_department_flow
└── utils
├── log_utils
└── utils
apis包下:可以划分多个功能模块
如:department中封装某个接口的增删改查方法,还可以有多个这样的模块;
tests包下:测试主逻辑 + 断言
config包下:配置公共变量,用于切换不同环境
如:提取公共BaseURL,请求参数等
参数可以封装到类中,直接根据类中方法获取想要的参数;
| 分层 | 作用 | 示例 |
|---|---|---|
| base_api | 封装和接口框架直接相关的方法 | 接口请求封装 |
| wework | 封装业务的全局操作 | 获取 token;获取配置数据 |
| department | 封装子模块的操作 | 部门信息的增删改查 |
| test_department | 测试步骤、业务流程及断言 | 添加部门用例 |
实际项目结构自己根据需求自定义:
示例:
3.接口自动化代码实现
封装单模块业务全局操作
创建一个功能模块的父类,封装业务该模块功能的公共方法;
如果是多个模块有公共方法,可以封装到baseApi方法中,让子类继承即可;
如下述是企业部门模块功能公共方法封装
java
/**
* 封装业务的全局操作
* 获取 token;
* 获取配置数据
*/
public class WeWork {
String corpid;
ConfigEntity configEntity;
public WeWork() {
configEntity = ConfigUtil.getConfig();
corpid = "sws37f7dsdd8sdb17ac";
//使用静态变量封装一个值,这样下述请求中不需要写公共的BaseUrl
//为当前测试会话中的所有 HTTP 请求设置统一的、基础的 URL 前缀。
RestAssured.baseURI = configEntity.getBaseUrl();
}
/**
* 获取token
* @param secret
* @return
*/
String getToken(String secret) {
Response response = given()
//获取请求的日志 参数信息 请求头 请求参数
.log().all()
.param("corpid", corpid)
.param("corpsecret", secret)
.when()
.get("/gettoken")
.then()
//获取响应日志 响应body 响应头信息
.log().all()
.extract().response();
return response.path("access_token").toString();
}
}
封装单模块下子模块的具体业务操作
封装部门下具体业务接口操作:
如:封装部门信息的增删改查,封装具体业务逻辑操作:只负责操作,不关心结果;
java
/**
* 与部门相关的操作:创建部门,删除部门,查询部门
* 接口请求CRUD逻辑
*/
public class WeWorkDepartment extends WeWork{
String secret;
public WeWorkDepartment() {
secret = configEntity.getContactsSecret();
}
/**
* 创建部门方法
* @param createEntity
* -请求体中的参数使用类来表示
* 调用者可以通过直接看实体类知道需要的参数
*/
public Response createDepartment(DepartmantCreateEntity createEntity) {
Response response = given()
.body(createEntity)
// 设置请求的内容类型为 JSON,并指定字符编码为 UTF-8
.contentType(ContentType.JSON.withCharset(StandardCharsets.UTF_8))
.log().all()
.when()
.post("/department/create?access_token=" + getToken(secret))
.then()
.log().all()
.extract().response();
return response;
}
/**
* 删除接口方法
*/
public Response delete(Integer depId) {
Response response = given()
.param("id", depId)
.when()
.post("/department/delete?access_token=" + getToken(secret))
.then()
.extract().response();
return response;
}
/**
* 查询ID
*/
public List<Integer> getIds() {
String dpsText = given()
.when()
.post("/department/simplelist?access_token=" + getToken(secret))
.then()
.extract().response().getBody().asString();
return JsonPath.read(dpsText, "$..id");
}
}
子模块业务的测试用例封装
子模块测试用例关注:测试步骤、业务流程及断言
java
**
* 测试用例: 主要关注业务逻辑,与用例输入和输出
*/
public class DepartmentApiObjectTest {
static WeWorkDepartment weWorkDepartment;
static WeworkMember weworkMember;
/**
* 前置处理-初始化对象
*/
@BeforeAll
static void setUp() throws IOException {
weWorkDepartment = new WeWorkDepartment();
weworkMember = new WeworkMember();
}
/**
* 参数化设置
*/
@ParameterizedTest
@MethodSource("util.TestDataFactory#getDepartmentCreateTestData")
void createDepartmentParams(DepartmantCreateEntity departmantCreateEntity) {
Response re = weWorkDepartment.createDepartment(departmantCreateEntity);
}
/**
* 测试用例业务逻辑实现
* 新增存在的部门
*/
@Test
void createDepartmentExist() {
//1.准备已存在的部门
DepartmantCreateEntity createDepartment = new DepartmantCreateEntity("技术部","zs",1,1,1 );
weWorkDepartment.createDepartment(createDepartment);
//2.有存在部门情况下,创建相同信息部门失败
Response response = weWorkDepartment.createDepartment(createDepartment);
MatcherAssert.assertThat(response.path("errcode"),is(60020));
//3.删除部门
weWorkDepartment.delete(createDepartment.getId());
//4.查询部门删除成功
List<Integer> ids = weWorkDepartment.getIds();
MatcherAssert.assertThat(ids, not(hasItem(createDepartment.getId())));
//5.再次创建部门
weWorkDepartment.createDepartment(createDepartment);
//6.查询部门创建成功
ids = weWorkDepartment.getIds();
assertThat(ids, hasItem(createDepartment.getId()));
}
}
优化
全局公共参数/变量提取
config-test.yaml文件中封装需要参数
xml
# 读取参数的配置文件
baseUrl: https://xxx.com
corpId: xxxx
contactsSecret: xxx
配置参数实体类:
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ConfigEntity {
private String baseUrl;
private String corpId;
private String contactsSecret;
}
读取yaml文件,yaml文件中包含提取的参数
java
/**
* 配置读取yaml文件的工具类
*/
public class ConfigUtil {
public static ConfigEntity getConfig() {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
//读取yaml文件并反序列化
return mapper.readValue(ConfigEntity.class.getClassLoader()
.getResourceAsStream("config-test.yaml"), ConfigEntity.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
封装后使用示例:
java
ConfigEntity configEntity = ConfigUtil.getConfig();
RestAssured.baseURI = configEntity.getBaseUrl();
其他优化考虑:
1.多环境切换配置:考虑生产环境,测试环境等
2.数据库配置:读取数据库数据作为数据源进行参数化测试
3.响应断言:面对复杂响应情况,多层嵌套响应,做出响应优化;
4.可以考虑参数化-使用Junit5方法
小技巧
1.封装参数:选择Map 或 类;如:请求体参数
推荐类封装参数,使用类让其他使用者调用,直接查看类就知道参数是什么;
2.如果用例数量很多,成千上万,怎么维护和保证运行效率?
维护:来源前期代码规范,接口自动化脚本编写有较好的约定 ,抽象,前期规范到位,后期容易维护;
运行效率:在保证接口用例之间没有资源争夺情况下,可以考虑使用多线程运行脚本;
总结
✨✨✨各位读友,本篇分享到内容是否更好的帮助你理解,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
🎉🎉🎉一遇挫折就灰心丧气的人,永远是个失败者。而一向努力奋斗,坚韧不拔的人会走向成功。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

