对于接口测试的方法,我们有多种选择,譬如:使用jmeter工具中的http请求,postman请求,和偏向代码层面的自动化接口测试框架。在分别使用这三者方法进行接口测试后,发现各有所优缺。

1、 postman比较适合单个接口测试请求,对于复杂的业务使用其进行自动化接口测试用例设计时比较繁琐。
2、 jmeter工具对于业务测试比较友好,可以通过前置条件和后置处理进行测试数据的构造,然后进行自动化接口测试用例的设计并执行,对于接口的测试结果输出比较直观。但是对于单个接口测试需要设计多个测试用例和测试数据,在后期的维护过程中不是很方便。
3、 自动化接口测试框架使用更偏向于单元测试层面,需要了解和懂得Java语言,对于测试结果的处理不是很友好,通过断言进行判断。在测试用例设计的过程中更全面一些,但测试结果没有jmeter工具那么直观。同时维护起来比较麻烦。

综上,在测试性能过程中了解了jmeter工具中的Java请求,如是尝试通过jmeter+Java+HttpclientUtil的使用进行接口测试。源码请下载:基于jmeter+Java+HttpclientUtil实现的接口测试工具

难点:

  1. 对于不同的系统接口比较多,所以需要针对每个接口设计一个类,并且类中需要继承JavaSampleClient类,类中需要包含getDefaultParameters(设置入参),setupTest(初始化方法),runTest(测试主体),teardownTest(测试结束)。每个类中含有大量重复数据并且每个方法的具体实现不同。因此,编写出的java请求比较冗余和且维护成本比较大。
  2. 测试响应结果的校验和断言需要针对每个测试用例进行设计,如果设计在代码里面维护比较麻烦而且场景覆盖比较低。如果借用jmeter工具的断言进行校验需要编写大量的BeanShell脚本。而且需要将接口响应结果直接打印。
  3. 接口参数每次改动都需要修改java请求的源码然后重新生成jar包增加了测试的工作量。相对于纯使用jmeter工具而言更复杂了。

针对以上的难点,研究了开发提供的单元测试后,针对上述问题进行了设计和解决。最终通过如下方法进行重新设计。

  • 重写一个类OverWriteJavaSampleClient继承JavaSampleClient类,并将JavaSampleClient类中的方法重定义overGettDefaultParameters、overSetupTest、overRun、overRunTest方法,然后再其中实现JavaSampleClient的具体方法;对于接口中的参数定义成一个实体类,包括code(编号)、title(接口名称)、url(请求路径)、requestType(请求类型)、paramType(参数类型)、headerMsg(消息头参数)、paramsMag(接口参数)、assertMsg(断言)、description(接口描述)。每个接口名称对应一个实体类,且接口的参数通过map键值对存储在list中。接口参数数据通过Excel读取获取后存储为对应的格式。在方法中通过实体类中的参数判断接口类型,参数类型进行HttpClientUtil工具类调用发送http请求。
  • 由于每个接口响应数据格式比较统一,只在代码中通过判断校验部分数据,具体的响应data里面的内容公共Jmeter工具进行校验。对于响应数据进行重新定义输出。
  • 每个接口需要对于一个类,但是类里面的实现只需要通过Excel表中的title来进行参数回去。因此,类中的实现表简单,基本是统一的,减少了代码的冗余,同时参数可通过Excel进行维护。

针对上述设计思路,并开始了设计实现。包括两个部分,Excel的定义和java脚本的实现。

Excel的定义

代码实现:
OverWriteJavaSampleClient类实现方法

public abstract class OverWriteJavaSampleClient extends AbstractJavaSamplerClient {Map<String,RemoteServerInfoEntity> setRemoteServerInfo;{try {setRemoteServerInfo = setRemoteServerInfo();} catch (Exception e) {e.printStackTrace();}}//自定义java请求方法入参,设置可用参数及默认值public Arguments overGettDefaultParameters(String key){Arguments params = new Arguments();params.addArgument("httpHost","");for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getHeaderMsg().entrySet()) {params.addArgument(stringStringEntry.getKey(),"");}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getParameterMsg().entrySet()) {params.addArgument(stringStringEntry.getKey(),"");}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getAssertMsg().entrySet()) {params.addArgument(stringStringEntry.getKey(),"");}return params;}public void overSetupTest(JavaSamplerContext arg0,String key) {String httpHost = arg0.getParameter("httpHost");for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getHeaderMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getParameterMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getAssertMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}}public String overRun(String httpHost, String key) {String respJson = "";StringBuilder urlBuff = new StringBuilder();urlBuff.append(httpHost).append(setRemoteServerInfo.get(key).getUrl());if(!setRemoteServerInfo.get(key).getHeaderMsg().isEmpty()) {if (setRemoteServerInfo.get(key).getRequestType() == 1) {respJson = HttpClientUtils.doGetRequest(urlBuff.toString(), setRemoteServerInfo.get(key).getHeaderMsg(), setRemoteServerInfo.get(key).getParameterMsg());} else {if (setRemoteServerInfo.get(key).getParamType() == 1) {respJson = HttpClientUtils.doPostRequest(urlBuff.toString(), setRemoteServerInfo.get(key).getHeaderMsg(), setRemoteServerInfo.get(key).getParameterMsg(), null);} else {StringEntity entity = map2StringEntity((HashMap<String, String>) setRemoteServerInfo.get(key).getParameterMsg());respJson = HttpClientUtils.doPostRequest(urlBuff.toString(), setRemoteServerInfo.get(key).getHeaderMsg(), null, entity);}}}else{if (setRemoteServerInfo.get(key).getRequestType() == 1) {respJson = HttpClientUtils.doGetRequest(urlBuff.toString(), null, setRemoteServerInfo.get(key).getParameterMsg());} else {if (setRemoteServerInfo.get(key).getParamType() == 1) {respJson = HttpClientUtils.doPostRequestwithCookie(urlBuff.toString(), null, setRemoteServerInfo.get(key).getParameterMsg(), null);} else {StringEntity entity = map2StringEntity((HashMap<String, String>) setRemoteServerInfo.get(key).getParameterMsg());respJson = HttpClientUtils.doPostRequestwithCookie(urlBuff.toString(), null, null, entity);}}}return respJson;}public SampleResult overRunTest(JavaSamplerContext arg0, String key){String httpHost = arg0.getParameter("httpHost");for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getHeaderMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getParameterMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getAssertMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));}//定义请求和响应相关信息,输出至生成结果树//生成结果树中请求消息和响应消息内容String title = " "+"\n"+"\t"+"                                   接口:"+setRemoteServerInfo.get(key).getDescription()+"                                  "+"\n"+"\t"+" "+"\n";String httpUrl = "HttpUrl:" + httpHost + setRemoteServerInfo.get(key).getUrl()+"\n";String requestBody = "";String assertMsg = "断言字段期望值:";for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getParameterMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));requestBody += "\n"+"\t"+"\""+ stringStringEntry.getKey()+"\""+":" + stringStringEntry.getValue() + ",     ";}for (Map.Entry<String, String> stringStringEntry : setRemoteServerInfo.get(key).getAssertMsg().entrySet()) {stringStringEntry.setValue(arg0.getParameter(stringStringEntry.getKey()));assertMsg += "\""+ stringStringEntry.getKey()+"\""+":" + stringStringEntry.getValue() + ",     ";}String requestJson = "RequestJson:"+"{" +requestBody+"\n" + "}"+"\n"+assertMsg;Map<String, String>  assertResult =new HashMap<>();SampleResult sr = new SampleResult();String request_msg = "";request_msg = request_msg + title+httpUrl + requestJson ;//+ assertMsg;String response_msg = "";response_msg = response_msg+title;try {sr.sampleStart();String runMap = this.overRun(httpHost,key);if(setRemoteServerInfo.get(key).getAssertMsg().containsKey("exp_code")){assertResult = AssertDeal.AssertDealofCodeMessage(runMap,setRemoteServerInfo.get(key).getAssertMsg());response_msg += assertResult.get("assertResult") ;sr.setSuccessful(Boolean.parseBoolean(assertResult.get("Bool")));}else if(setRemoteServerInfo.get(key).getAssertMsg().containsKey("exp_total")){assertResult = AssertDeal.AssertDealofTotalResult(runMap,setRemoteServerInfo.get(key).getAssertMsg());response_msg += assertResult.get("assertResult") ;sr.setSuccessful(Boolean.parseBoolean(assertResult.get("Bool")));}else {if(!runMap.equals(null)) {response_msg += runMap;sr.setSuccessful(Boolean.parseBoolean(assertResult.get(true)));}else {response_msg += runMap;sr.setSuccessful(false);}}}catch (Throwable e){sr.setSuccessful(false);e.printStackTrace();}finally {sr.sampleEnd();}System.out.println(request_msg);sr.setRequestHeaders(request_msg);sr.setResponseData(response_msg,"utf-8");System.out.println(response_msg);return sr;}// 结束方法,实际运行时每个线程仅执行一次,在测试方法运行结束后执行public void overTeardownTest(JavaSamplerContext arg0) {}public Map<String,RemoteServerInfoEntity> setRemoteServerInfo() throws Exception {List<Map<String, String>> line = (List<Map<String, String>>) getLine("E:\\JmeterTest\\file\\interfaceParam.xls");int lineSize = line.size();Map<String,RemoteServerInfoEntity> paramsSet = new HashMap<>();try {for(int i=0;i<lineSize;i++) {Integer getCode = Integer.parseInt(line.get(i).get("code"));String getUrl = line.get(i).get("url");int getRequestType = Integer.parseInt(line.get(i).get("requestType"));int getParamType = Integer.parseInt(line.get(i).get("paramType"));String getTitle = line.get(i).get("title");Map<String, String> getHeader = string2Map(line.get(i).get("headerMsg"));Map<String, String> getParams = string2Map(line.get(i).get("paramsMsg"));Map<String, String> getAssert = string2Map(line.get(i).get("assertMsg"));String getDescription = line.get(i).get("description");RemoteServerInfoEntity param = new RemoteServerInfoEntity();param.setCode(getCode);param.setUrl(getUrl);param.setParamType(getParamType);param.setRequestType(getRequestType);param.setTitle(getTitle);param.setHeaderMsg(getHeader);param.setParameterMsg(getParams);param.setAssertMsg(getAssert);param.setDescription(getDescription);paramsSet.put(getTitle, param);}} catch (Exception e) {e.printStackTrace();}return paramsSet;}}

举个栗子
登录接口java请求脚本

public class Login extends OverWriteJavaSampleClient {String key = "login";//自定义java请求方法入参,设置可用参数及默认值public Arguments getDefaultParameters(){Arguments params =overGettDefaultParameters(key);return params;}// 初始化方法,实际运行时每个线程仅执行一次,在测试方法运行前执行// 每个线程测试前执行一次,做一些初始化工作;public void setupTest(JavaSamplerContext arg0){overSetupTest(arg0,key);}@Overridepublic SampleResult runTest(JavaSamplerContext arg0) {SampleResult sr = overRunTest(arg0,key);return sr;}// 结束方法,实际运行时每个线程仅执行一次,在测试方法运行结束后执行public void teardownTest(JavaSamplerContext arg0) {overTeardownTest(arg0);}

代码层执行结果:

接口测试工具设计与实现相关推荐

  1. 接口测试,接口协议以及常用接口测试工具介绍

    一.前言:什么是接口 1.接口指的是软件提供给外界的一种服务.作用在于使其内部的数据能被外部进行修改的交互方式. 例如:USB接口,电脑里的数据可以看成是内容数据,而U盘里的数据可以看成是外部数据,那 ...

  2. java接口测试工具_接口测试基础了解篇

    什么是接口测试? 接口测试又称为API测试,是测试系统组件间接口的一种测试,属于灰盒测试范畴. 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交 ...

  3. 平台服务器测试3—接口测试工具实现

    平台服务器的接口测试用例及测试数据准备完毕后,接下来的工作就是如何去进行接口功能测试了,如果使用客户端来进行平台服务器的接口测试,不但某些测试用例无法进行覆盖(例如上传不合法的版本号),而且有的输入值 ...

  4. 数据接口测试工具 Postman 介绍

    此文介绍好用的数据接口测试工具 Postman,能帮助您方便.快速.统一地管理项目中使用以及测试的数据接口. 1. Postman 简介 Postman 一款非常流行的 API 调试工具.其实,开发人 ...

  5. java接口测试工具_【分享】接口工具对比(apipost、jmeter、postman、swagger等)

    一.接口都有哪些类型? 接口一般分为两种:1.程序内部的接口 2.系统对外的接口 系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把 数据库共享给你,他只能给你提供一个他们写好 ...

  6. 盘点下常用的接口测试工具,有几个你肯定没用过

    在项目开发.部署过程中, 总免不了要对服务的一些接口进行简单的测试和验证, 在很多时候都是在服务器环境, 因此掌握一个命令行http接口测试工具还是非常有必要的, 我常用的主要有三个, wget.cu ...

  7. API接口测试及常用de接口测试工具

    首先,什么是接口呢? 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口. 系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们 ...

  8. 接口测试、接口协议以及常用接口测试工具介绍

    目录 一.前言:什么是接口 二.接口协议以及对应的接口测试工具 三.接口测试如何设计测试用例? 四.接口组成? 五.总结 一.前言:什么是接口 1.接口指的是软件提供给外界的一种服务.作用在于使其内部 ...

  9. 好用的API接口测试工具有什么推荐吗?

    点击上方关注 "终端研发部" 设为"星标",和你一起掌握更多数据库知识 这篇文章,推荐一些还不错的工具,具体工具使用,是没有任何门槛:搜索引擎,去搜索工具名,有 ...

  10. 2021全网最全接口测试及常用接口测试工具

    首先,什么是接口呢? 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口. 系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们 ...

最新文章

  1. 360董事长周鸿祎发表全员信:疫情当前,要做好长期在家办公的准备
  2. deepfefm 算法思维导图
  3. linux平台及windows平台mysql重启方法
  4. et超排真正免狗能用版 真正好用的东西_真正合格小户型,收纳都特别能“装”...
  5. AngularJS中的过滤器(filter)
  6. GitHub进一步了解
  7. spring4.x(4)--SpringIOC的HelloWorld
  8. rocketmq新扩容的broker没有tps_揭秘 RocketMQ 新特性以及在金融场景下的实践
  9. 360卸载方法(最全面)
  10. Cannot currently show the desktop
  11. 何为自动化测试?(纯干货)
  12. 你应该问面试官的10个相关问题
  13. Invalid parameter passed to C runtime function.
  14. 【C语言编程练习】20050. 计算存款利息
  15. Python代码大全,海量代码任你下载
  16. JavaScript数组常用方法解析和深层次js数组扁平化
  17. 在谷歌上安装倍速播放的插件video-speed-controller
  18. 快速检查(QuickCheck)(译)
  19. vscode开启LiveReload出错
  20. 30个漂亮的网页设计案例

热门文章

  1. 计算机网络实践报告--网络安全
  2. Gradle基础教程
  3. 数据分析第二章课后习题解答
  4. imac 蓝牙机械键盘_最好的蓝牙机械键盘
  5. php实现给pdf加水印,pdf文件如何加水印 怎样给pdf文件加水印|帮你轻松实现给pdf加水印...
  6. 大数据技术——Spark实时计算
  7. ant design pro模板_ant design pro超详细入门教程
  8. xui和嘟嘟桌面哪个好_小米国际版桌面,这是我用过最流畅的手机桌面
  9. cad图纸服务器共享文件慢,DWG文件打开慢?3个技巧教你实现快速预览!
  10. 雄迈XM530AI / 550AI模组相关参数介绍