上一次提到如果我有时间了会把最近在做的接口自动化分享出来,今天我将从框架、设计、测试类三方面进行分享。可能有不足或者可以优化的地方,欢迎指正,有想法的小伙伴可以在后台与我联系哦!
我这边用的是Java语言,基于TestNG测试框架,支持持续集成,自动构建与测试。主要有以下几个特点:
数据驱动设计,使用TestNG中的@DataProvider读取Excel中存储的自动化测试用例。
使用HttpClient发送Http请求,并统一接口response返回值为String
使用fastJson进行数据解析
AssertJ用于检查点设置
Maven进行项目、依赖管理
我负责的是扣缴组的接口自动化的搭建,其实我对业务并没有很熟悉,但这影响不大,简单走一下流程基本上就可以开始动手了。


api:http接口
common:公用类
dto:数据传输对象,用于展示层与服务层之间的数据传输对象。
api

扣缴组的接口自动化要同时维护客户端和Web端,所以前期我踩了一些坑,本来想着封装一个request和一个response,在测试类里区分端,最后发现这个方法不可取,因为登录方式完全不一样,后来我干脆就分开写了。
common

dto

看到这里基本上已经有比较清晰的思路了,内容主要集中在common公用类,下面我们详细看下每个类封装了什么内容。
下面对common里的每一个类进行分析,因为涉及到业务,所以我只能适当截图+轻描淡写,相信聪明如你,一眼就会。
一、【客户端】
HttpKhdRequest 客户端的登录请求
请求的URL和端口号从config.properties取;
请求的用户信息从user.properties

请求接口

因为登录客户端需要获得安全认证和获取token,所以AuthorizationHq和tokenhqbyTyrk单独拿出来写。
AuthorizationHq

tokenhqbyTyrk

备注:dto下的UserDTO在这里使用到。
ApiKhdResponse 客户端返回 查看了下接口文档,返回基本是这些信息。

所以我的返回类的封装主要包含以下内容:
- public class ApiKhdResponse {
-
- private String type;
-
- private Object data;
-
- private String errorCode;
-
- private String errorMessage;
-
- private String reason;
-
- public JSONObject convert2JsonObject() {
- String dataText = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
- JSONObject dataObject = JSON.parseObject(dataText);
- return dataObject;
- }
-
- public JSONArray convert2JsonArray() {
- String dataText = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
- JSONArray dataArray = JSON.parseArray(dataText);
- return dataArray;
- }
-
- public String getType() {
-
- return type;
- }
-
- public void setType(String type) {
-
- this.type = type;
- }
-
- public void assertSuccess(){
- String type=getType();
- assertEquals("SUCCESS", type);
- }
-
-
- public void assertFailed() {
- String type=getType();
- //有些返回失败的接口,type返回ERROR
- if (StringUtils.isEmpty(type)) {
- assertTrue(true);
- return;
- }
- assertTrue(!type.equals("SUCCESS") && !type.contains("ERROR"));
- }
-
-
-
- public Object getData() {
- return data;
- }
-
- public void setData(Object data) {
- this.data = data;
- }
-
- public String getErrorCode() {
- return errorCode;
- }
-
- public void setErrorCode(String errorCode) {
- this.errorCode = errorCode;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- public String getReason() {
- return reason;
- }
-
- public void setReason(String reason) {
- this.reason = reason;
- }
-
- @Override
- public String toString() {
- return "ApiResponse{" +
- "type='" + type + '\'' +
- ", data=" + data +
- ", errorCode='" + errorCode + '\'' +
- ", errorMessage='" + errorMessage + '\'' +
- ", reason='" + reason + '\'' +
- '}';
- }
-
- public <T> T getBodyBean(Class<T> clazz) { return JSON.parseObject(data.toString(), clazz); }
-
-
- }
-
备注:

这块内容不要手写,容易出错,IDEA能自动带出来。

RestUtil 客户端安全验证
我这边主要用到的是Hmac加密算法和AES加密算法。
TokenUtil 客户端生成token
二、【Web端】
HttpWebRequest Web端的登录请求

请求接口

getAuthorizationToken是结合我们的实际情况来写的(有个MOCK平台),我们通过接口平台进行授权登录。
ApiWebResponse Web端返回
查看了下接口文档,返回基本是这些信息。

所以我的返回类的封装主要包含以下内容:
- public class ApiWebResponse<T extends Object> {
-
- @Getter
- private String code;
- @Getter
- private Object[] params;
- @Getter
- private String message;
- @Getter
- private Object data;
- @Getter
- private String appCodeForEx;
- @Getter
- private String originalErrorCode;
-
-
- /**
- * rid
- */
- @Setter
- @Getter
- private String rid;
-
- /**
- * @param code
- * @return
- */
- public ApiWebResponse<T> setCode(String code) {
- this.code = code;
- return this;
- }
-
- public String getCode() {
-
- return code;
- }
-
-
- /**
- * @param message
- * @return
- */
- public ApiWebResponse<T> setMessage(String message) {
- this.message = message;
- return this;
- }
-
- public String getMessage() {
-
- return message;
- }
-
- /**
- * @param data
- * @return
- */
- public ApiWebResponse<T> setData(Object data) {
- this.data = data;
- return this;
- }
-
-
- public Object getData() {
- return data;
- }
-
- /**
- * @param params
- * the params to set
- */
- public ApiWebResponse<T> setParams(Object[] params) {
- this.params = params;
- return this;
- }
-
- public Object[] getParams() {
-
- return params;
- }
-
- public JSONObject convert2JsonObject() {
- String dataText = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
- JSONObject dataObject = JSON.parseObject(dataText);
- return dataObject;
- }
-
- public JSONArray convert2JsonArray() {
- String dataText = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
- JSONArray dataArray = JSON.parseArray(dataText);
- return dataArray;
- }
-
- public static boolean isSuccess(ApiWebResponse<?> apiResponse) {
- boolean success = false;
- if (apiResponse == null) {
- return success;
- }
- if ("SUCCESS".equals(apiResponse.getCode())) {
- success = true;
- }
- return success;
- }
- }
XmlParserUtil 解析工具
这个类的封装主要包含基础路径、获取账户信息、获取文件路径信息。
基础路径

获取账户信息

备注:dto下的ZhxxDTO在这里使用到。
获取文件路径信息

三、【数据库】
DBUnitBaseTest

数据库信息的话如果有新增数据库或者在业务迭代过程中拆分数据库的情况都需要去dataBase.xml和DBUnitBaseTest维护,否则用例会执行不通过。关于这块内容我同事有其他的建议,我以后再向其学习。
api

zhxx 这里维护的是Web端的不同环境的账号,对应的是java接口代码下的dto,这个每个项目不一样,不一定都会有。
其实我们前面写那么多的代码只是为了让我们编写测试类接口的时候可以少写一点代码,不信你看:

接下来我们练习写一个扣缴Web端接口。
1.首先回顾下结构

2. 着手编写接口
2.1在web端请求接口,抓包获取接口。

2.2查看接口文档。

2.3开始编写
2.3.1添加测试类
右击添加Package,层层添加,直到最后一层右击添加Java Class。

2.3.2编写接口代码
- package com.XXX.api.kjweb.zrr.XXXX;
-
- import com.alibaba.fastjson.JSON;
- import com.XXX.common.ApiWebResponse;
- import com.XXX.common.DBUnitBaseTest;
- import com.XXX.common.HttpWebRequest;
- import com.XXX.api.util.AssertUtil;
- import junitx.framework.Assert;
- import org.springframework.http.HttpMethod;
- import org.testng.annotations.Test;
- import ru.yandex.qatools.allure.annotations.Title;
-
- import java.util.HashMap;
- import java.util.Objects;
-
- import static org.testng.AssertJUnit.assertEquals;
-
- /**
- * create by lxl01 on 2021/5/18
- */
- @Title("自然人基本信息查询")
- public class QueryTest extends HttpWebRequest {
- @Test(dataProvider = "excel", groups = {"kjweb_http"})
- public void testQuery(String run, String testname, String yhm, String device,String data, String expectData) {
- //接口请求
- String Api = "/web/zrr/XXXX/query";
- //接口返回
- ApiWebResponse response = requestKjd(Api, HttpMethod.GET, JSON.parseObject(data, HashMap.class), yhm,device);
- //验证实际返回结果与预期结果一致(只校验data)
- assertEquals(Objects.toString(response.getData(), ""), expectData);
- }
- }
-
2.4 细节讲解
2.4.1包的导入,引用到什么就导入什么。
2.4.2表字段包含run、testName、yhm、device、data、expectData,可以参考下方,按需添加。

2.4.3接口请求 直接把URL放上去
2.4.4接口返回
ApiWebResponse 是单独封装的作为扣缴Web端的返回校验的类,在common下。
requestKjd 是单独封装的作为扣缴Web端的请求的类,在common下。
2.4.5校验
校验什么内容可以根据业务需要+接口文档进行编写。我们先看下这个接口的返回数据都有哪些。

以下分享几种我常用的校验
A.校验全部返回-第一种校验方法
Assert.assertEquals(Objects.toString(response, ""), expectData);
得出的结果是

B.校验全部返回-第二种校验方法
AssertUtil.isJsonEquals(response, expectData,false);
得出的结果是

A和B使用时需要导入不同的包,二者的区别可以左击到对应类查看,都是底层封装好的共用的类。
A 导入 import junitx.framework.Assert;

B 导入 import com.xqy.api.util.AssertUtil;

C 校验返回的data数据
assertEquals(Objects.toString(response.getData(), ""), expectData);
得出的结果是

其中getData是我在ApiWebResponse类里封装好的

D 校验数据库
JsonUtils.assertDBEquals(jdbcTemplateOfSb, returnSql, returnDB);
调试与执行
编写完之后在测试类点击执行,如果执行的时候报错了,根据控制台的提示进行debug。
至于如何在遇到问题时进行debug可以看下我之前写的文章,标题为《如何debug排查问题以及解决冲突》。
本文其实可以倒着看,先看测试类,再看前面的内容。为啥这个测试类能执行通过是因为前面的搭建基础;而为啥前面要搭建基础,因为后面维护测试类很简洁、方便。
好啦,文章内容就更新到这里,我要下班了。
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走

这些资料,对于想【进阶测试开发】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。希望对大家有所帮助…….
