# bugdar **Repository Path**: rd_ddddd/bugdar ## Basic Information - **Project Name**: bugdar - **Description**: 一个基于java+TestNG+Mybatis的http接口测试框架 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2022-01-29 - **Last Updated**: 2022-11-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 简介: 一个java的接口自动化测试框架,主要分为三个部分: 1. 全局工具类 2. 用例数据的维护 3. 通过DataProvider将用例数据传给测试用例,实现数据驱动 使用方式: ========= 1.使用bugdar.sql的语句进行建表, global_options为当前产品的全局设置,被测产品的产品名、测试环境与对应的主域名 test_case_http_request表为维护的具体数据,整体结构比较清晰,部分字段说明如下: * test_method_name:用到@DataProvider提供测试数据的需要和测试方法的测试名保持一致,我们会根据这个字段查询结构的相关字段;如果只是用于维护接口数据,没有用到@DataProvider字段则不需要考虑 * skipParams:针对JSON或实体类遍历验证时,跳过不需要验证的字段,通过["id","creat_time"]的字符串列表格式维护 * is_only_match_keywork:用于标识该用例是否只需要通过关键词匹配,我们提供了统一的方法,可以直接验证所有的用例,无需另外编写测试用例 * json_path_exception:用于维护需要验证的关键字所在的json路径、验证方式与预期值: * 目前提供了等于、不等于、包含关键字、不包含关键字和多种关键字符合一个的方式,分别对应EQUAL/NOT_EQUAL/IN/NOT_IN/OR(大写,通过下划线分隔) * jsonpath目前为绝对路径,路径格式为data.list[0].json.path,json对象不需要加后缀,json数组通过[1]表示索引,在chrome浏览器的返回值预览页,可以通过右键-复制路径的方式直接获取到 * 数据格式如下: ```json [{ "expectValue": "预期的值", "path": "data.apiName", "type": "EQUAL" }, { "expectValue": "预期的值", "path": "data.apiName", "type": "EQUAL" }] ``` 2.配置文件调整 1).在application.properties文件中写入以下节点: test.product.name=testprodcut ##对应global_options表中product_name字段 test.env=test ##对应test_enviroment字段 2).db.properties、mybatis.xml均根据实际的数据库表情况来调整链接设置; 3.实现一个http请求的验证: 1).使用@DataProvider,需要提前在test_case_http_request表中维护好对应的数据 ```java @Test(dataProvider = DataProviderManger.DATA_PROVIDER_NAME_REQUEST) public void getData(TestCaseHttpRequestVO request){ HttpResponseVO responseVO = HttpRequestUtil.sendHttpRequest(request); int code = responseVO.getCode(); HashMap header = responseVO.getHeader(); String resp =responseVO.getResponseBody(); //后续自行编写断言逻辑 } ``` 2).不使用@DataProvider,自行通过caseName用例名获取对应的测试数据: ```java @Test public void getDataAndRunTest(){ DataProviderManger manger = new DataProviderManger(); String caseName = "getData"; TestCaseHttpRequestVO requestVO = manger.getHttpRequestVOByCaseName(caseName); HttpResponseVO responseVO = HttpRequestUtil.sendHttpRequest(requestVO); int code = responseVO.getCode(); HashMap header = responseVO.getHeader(); String resp =responseVO.getResponseBody(); //后续自行编写断言逻辑 } ``` 3).关键字匹配的用例,在test_case_http_request表设置is_only_match_keywork=1,通过以下方法可以全部执行: ```java /**使用此方法,针对只需要根据json中关键字断言的异常判断场景,无需另外执行断言,只需要维护数据即可 * @param request */ @Test(dataProvider = DataProviderInitalize.DATA_PROVIER_NAME_ONLY_MATCH_KEYWORD) public void testAllException(TestCaseHttpRequestVO request){ boolean result= AssertUtil.runAndAssertOnlyMatchKeyWord(request); Assert.assertTrue(result); } ``` 全局工具类: =========== 工具类主要包括以下内容: * http参数处理 * 发送http请求 * 断言工具类 * json处理工具类 PS:所有工具类中的JSON处理均使用fastjson进行 http参数处理 ------------ http参数处理主要包括各种http格式参数的转换,相关内容请参见代码注释 * 将URL参数格式k1=v1&k2=v2转为Map格式,用于表单提交 * 将map格式参数转化为url格式字符串 * JSON参数转为Map * 针对部分在路由中传入的参数,通过${paramKey}的格式做参数化处理 发送http请求 ----------- 这一部分主要是使用HttpClient发送http请求,获取返回值,做的一点微小工作是统一发送格式,对不同的请求方法、ContentType等整合到了一起 如果不需要后续断言,只需要发送请求,可以参考如下写法: ```java public void testResp() { String url = "http://127.0.0.1:2333/httprequest/detail"; HashMap urlParam = new HashMap<>(); urlParam.put("id", "1"); url = HttpParamUtil.urlParameterization(url, urlParam); HashMap header = setHeader(); CookieStore cookie=setCookie(); HttpResponseVO responseVO = HttpRequestUtil.sendHttpRequest(url, header, cookie, "GET", null); int code = responseVO.getCode(); HashMap header = responseVO.getHeader(); String resp =responseVO.getResponseBody(); } ``` 断言工具类 -------- 所有接口自动化测试都绕不开的一个话题:如何做返回值验证?异常场景、参数验证还说,简单匹配下关键字基本也能做到七七八八,那么涉及到数据CURD,或者是其他的业务场景,怎么验证? 能不能轻松一点,找个通用的方法呢? 答案是可以的, 如果我们多接触一些项目的后端代码,那么大家都会发现,无论什么语言,对CURD的操作都是类似的: * 新增数据:从请求中获取json或map,反序列化成实体类,通过ORM映射后,将结果存入数据库;在这个过程中大部分字段都是直接按照入参直接存库,少部分字段做特殊处理 * 查询数据:从数据库查询到的数据,进行ORM映射处理后,再序列化为json字符串,返回请求方;在这一部分大部分字段也都是是直接按照查询结果返回,少部分字段做特殊处理 * 修改数据:整体与新增一致 * 删除数据:无论是逻辑删除,还是物理删除,体现在查询列表上,一定是无法查询到; 基于这个前提,我们的测试思路就可以变得非常简单:以新增场景为例 构造新增入参->调新增/编辑接口->查询列表或者详情->获取详情 新增数据时获取到的详情数据,可以用于后续的其他场景的验证 CURD结果验证 ------ 按照这个思路,我们只需要排除掉一些自增id、时间戳以及一些其他业务另行处理的字段,遍历对比新增时的参数与详情参数,每个字段一致即可;而确实有需要单独验证的场景拿出来单独验证下即可 ```java String reqbody= setBody();//新增时的入参 String resp = getResp();//获取返回值 List sikpParams = ["id","update_time"];//不需要验证的字段列表 //入参顺序为新增的数据在前,查询到的返回值数据在后,字段一一遍历验证,跳过列表中的字段 //JSONObject、实体类处理方式一致,只需要自行获取JSONObject对象或者反序列化为对应实体类即可 boolean result = AssertUtil.compareJSONObject(reqBody,resp,skipParams) //无skipParams的写法; boolean result = AssertUtil.compareJSONObject(reqBody,resp) ``` 支持以下类型的格式对比: * 入参为JSON字符串、返回值为JSON字符串 * 入参为JSONObject,返回值为JSONObject * 入参为JSONObject,返回值为实体类类型 * 入参为实体类类型,返回值为实体类类型 这里JSONObject使用的是fastjson提供的,如果你选择把json字符串反序列化为对应的实体类对比,那么应该不会受到json处理组件不同的影响 测试结果输出日志样式如下: > 当前验证字段:msg,新增时的参数:;详情参数: > > 当前验证字段:code,新增时的参数:2000;详情参数:2000 > > data的值依然为json对象,进入递归 > > 当前验证字段:apiDescribe,新增时的参数:当前为第1个接口;详情参数:当前为第1个接口 > > 当前验证字段:simpleVerify,新增时的参数:false;详情参数:false JSON工具类 ------- JSON工具类比较简单,主要是根据json绝对路径格式data.data[0].data.data格式直接取出对应的json值,具体参见源码注释 针对异常场景,很多时候返回给API的是一个固定的提示,我们提供了根据json路径+预期值的格式,验证返回值,相关样式参见全局说明 ```java List jsonPathExpectionList = setList(); boolean result = isJSONPathExcpection(resp,jsonPathExpectionList); ``` 我们同时集成了jsonpath依赖,给有需要的同学使用;考虑到jsonpath本身已经十分成熟了,我们并没有做进一步的封装