优秀的接口测试工具这么多,我到底该选择哪一种?

自动化测试技术的火热除了表现在UI层,还表现在接口层。能实现接口测试的工具和框架有很多,例如jmeter、postman、eoLinker、Request+Unittest等等。每一种工具或框架都有优缺点。选择哪一种,需要根据自身和公司的实际情况来决定。

一、选型

eoLinker纯图形界面、零代码量使用方便,支持在浏览器中安装插件,且提供了测试用例的管理,可以自动化执行所有用例。但网页版所有数据都是保存在服务商的数据库中,若公司涉及到保密问题,则不可以使用网页版,且纯图形界面不支持上传附件这类接口的测试。虽然开源版支持本地部署,但是功能非常的少。全功能本地部署,费用昂贵。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Request+Unittest是测试框架,纯代码级,python语言。应对各种需求,开发起来都很灵活。但是相对于图形化的工具而已,对人员水平要求较高,上手速度明显慢于图形化工具。若公司中有专门的接口自动化测试开发团队,这将是一个很好的选择。既然是语言开发类,也可以使用java+testng,可根据团队的语言能力,选择开发框架。
Postman大部分web项目的开发人员和测试人员都会选择使用这个工具。图形化的界面,操作方便,执行结果易阅读,易调试。可以实现自动化批量运行。但免费版仅支持http和https协议,且无法读写数据库。
在这里插入图片描述
在这里插入图片描述
Jmeter支持很多种类的协议,支持从数据库动态取值,支持第三方插件,支持接口对文件的操作。由于代码是开源的,即便没有支持的协议,也可以进行二次开发来完成。但测试报告偏向于性能,大部分是性能指标,且断言功能不够强大,虽然提供了beanshell断言,但是提高了使用门槛,需要一点的编程能力。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了节省成本,我选择开源软件。为了降低开发时间,我选择图形化的工具,减少脚本的编写。我自身具备一定的开发能力,且需要做性能测试,所以我选择Jmeter。在开发完性能测试脚本后,只要稍加修改,就可以获得接口自动化测试脚本。大家还是需要根据自身情况合理选择工具。
选择好工具后,编写测试脚本。我们需要创建线程组、配置元件以及一系列的请求。这些都是入门的内容,百度上都有,这里就不说了。下面给大家分享一下每个项目都用的着的一些技巧:①如何提取响应结果中的某个参数?②获得参数后,如何使用?③如何让系统自动判断响应结果是否正确?

二、提取参数

在实际项目中,有很多场景需要使用到响应结果中的参数。例如登录的响应结果中包含了token,后续的请求,都要使用这个token作为身份认证。例如QQ邮箱中修改一封草稿邮件,在修改之前,我们要获取这封邮件的sid。例如需要确认某个请求响应时间是否在5秒以内,我们需要获取发送时间和响应时间。
目前很多项目的接口返回参数,都是以json格式去发送的。所以我们可以用json提取器来获取想要的参数。若不是json格式,我们可以使用万能的正则表达式提取器来提取。除了这2种常用的方法外,jmeter还提供了近10种方法。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
第一种方法,json提取。选中登录请求,选择后置处理器→json提取器。
Names of created variables:变量名
JSON Path expressions:需要提取内容的路径
Match No.(0 for Random):提取第几个匹配的值(若有N个匹配的值,0表示随机取值,-1表示全部取值,1表示取第1个,2表示取第2个。。。N表示取第N个)
Compute concatenation var (suffix_All):勾选表示取所有的值,并保存到一个变量中,命名方式是第一行设置的变量名加上_All
Default Values:没有提取到值,将给变量一个默认值
下面举例说明

1.{  
2.    "errno": 0,  
3.    "data": {  
4.        "user_name": "zhangsan",  
5.        "mobile": "19900000001",  
6.        "created_at": "2019-09-06 15:55:21",  
7.        "real_name": "张三",  
8.        "group_info": {  
9.            "user_info": {  
10.                "mobile": "17700000001",  
11.                "created_at": "2019-09-06 15:55:21",  
12.                "token_type": 2,  
13.                "user_role": "普通用户",  
14.                "login_count": 188,  
15.                "password": "123456",  
16.                "updated_at": "2019-09-06 15:55:21",  
17.                "id": "991222",  
18.            },  
19.            {  
20.                "mobile": "17700000002",  
21.                "created_at": "2019-09-21 11:33:16",  
22.                "token_type": 2,  
23.                "user_role": "普通用户",  
24.                "login_count": 157,  
25.                "password": "123456",  
26.                "updated_at": "2019-09-22 09:50:01",  
27.                "id": "991223",  
28.            },  
29.        },  
30.        "token_type": 2,  
31.        "access_token": "d791640014b411eabf110bd02de67c73",  
32.        "login_count": 871,  
33.        "user_id": "331236",  
34.        "finger_sign": "147"  
35.    },  
36.    "errmsg": ""  
37.}  

这是一个登录后的响应请求,若我们需要提取access_token,则可以这样设置
在这里插入图片描述
第一行设定变量名为token,第二行根据给定的路径进行查找,找到后将值赋给token。若找不到,将最后一行的“nodata”赋给token。根据$.data.access_token,我们可以找到第31行的d791640014b411eabf110bd02de67c73并将他赋给token,以后的请求,我们都可以使用这个变量token了。
在这里插入图片描述

如果我们要提取电话号码,则$.data.group_info.user_info.mobile会匹配到第10行和第20行,这里的Match No 我设置的是0,代表随机获取这2个号码中的一个赋给phone。并将两行的内容保存到变量phone_ALL里。
Json提取器很简单,能否准确提取到想要的内容,主要就是JSON Path expressions设置的正确与否。在第一篇selenium自动化测试中,我们说过Xpath,其实json path与之类似,具体语法对比如下
在这里插入图片描述

1.{ "store": {  
2.    "book": [  
3.      { "category": "reference",  
4.        "author": "Nigel Rees",  
5.        "title": "Sayings of the Century",  
6.        "price": 8.95  
7.      },  
8.      { "category": "fiction",  
9.        "author": "Evelyn Waugh",  
10.        "title": "Sword of Honour",  
11.        "price": 12.99  
12.      },  
13.      { "category": "fiction",  
14.        "author": "Herman Melville",  
15.        "title": "Moby Dick",  
16.        "isbn": "0-553-21311-3",  
17.        "price": 8.99  
18.      },  
19.      { "category": "fiction",  
20.        "author": "J. R. R. Tolkien",  
21.        "title": "The Lord of the Rings",  
22.        "isbn": "0-395-19395-8",  
23.        "price": 22.99  
24.      }  
25.    ],  
26.    "bicycle": {  
27.      "color": "red",  
28.      "price": 19.95  
29.    }  
30.  }  
31.}  

示例表达式:
$.store.book[].author:商店所有书籍的作者(四个作者)
$…author :所有作者
$.store.
:商店所有的东西,包括book和bicycle
$.store…price :所有东西的价格
$…book[2] :第三本书
. . b o o k [ 0 , 1 ] / ..book[0,1] / ..book[0,1]/…book[:2] :前两本书
?$…book[?(@.isbn)] :用isbn编号过滤所有书籍
$…book[?(@.price<10)] :过滤所有比10更便宜的书
$…* :XML文档中的所有元素
第二种方法,正则表达式提取。
在这里插入图片描述

和json类似,关键就在表达式"access_token":"(.*?)"
在响应的数据中,其中有一行是这样的:
1.“access_token”:“d791640014b411eabf110bd02de67c73”,
那么我们的表达式,括号中的内容,就代表要提取的内容;
.号代表匹配任意字符串;
+号代表匹配一次或多次;
*号代表匹配任意次(包括0次);
?号代表不要贪婪,找到第一个匹配项,就停止匹配;
正则表达式的语法比较复杂,这里就不过多的介绍了,有兴趣可以自己搜集资料,去练习。

三、参数传递

参数传递分为两类,线程内传递、线程间传递。以上面提取到的token为例,若想使用这个参数,在线程内是这样写的:${token}
在这里插入图片描述
跨线程传递,需要借助beanshell取样器,先将变量通过setProperty函数设置为全局变量,然后其他线程再通过P函数去引用,具体做法如下:
在这里插入图片描述
在这里插入图片描述

登录和设置全局变量 这2个请求在同一个线程组内,所以登录请求获取到的token,在设置全局变量的请求中,可以直接使用 t o k e n , 前 面 的 “ a l l T h r e a d U s e T o k e n ” 是 全 局 变 量 名 , 可 以 随 便 起 , 自 己 记 得 住 就 行 , 最 好 做 到 见 名 知 意 。 “ 第 一 次 登 录 需 要 设 置 手 势 密 码 ” 这 个 请 求 和 登 录 请 求 在 不 同 的 线 程 组 , 所 以 无 法 直 接 使 用 {token},前面的“allThreadUseToken”是全局变量名,可以随便起,自己记得住就行,最好做到见名知意。 “第一次登录需要设置手势密码”这个请求和登录请求在不同的线程组,所以无法直接使用 tokenallThreadUseToken便线使{token},必须使用allThreadUseToken,格式为${__P(allThreadUseToken)},如下图:
在这里插入图片描述

四、断言

所有请求都可以运行起来,我们还需要检查他的响应结果是否正确。Jmeter提供了很多断言方式,和上述的json提取器的样式类似,设置都很简单。下面对beanshell断言进行一个介绍,因为其比较灵活,可以自己写断言内容。
在这里插入图片描述

1.if("${realTime}".equals("0")){  
2.    Failure = true;  
3.    FailureMessage = "没有获取到时间信息";  
4.}else if("${realCode}".equals("{__P(sendCode)}")){  
5.long t = Long.valueOf("${realTime}")-Long.valueOf("${__P(sendTime)}");  
6.if(t < 0){  
7.    t = 0 - t;  
8.}  
9.if(t <= 5){  
10.    Failure = false;  
11.    FailureMessage = "服务器的响应时间为" + t + "S" +   
12.        "----响应时间戳:${realTime};发送时间戳:${__P(sendTime)}";  
13.    }else{  
14.        Failure = true;  
15.        FailureMessage = "服务器的响应时间为" + t + "S" +   
16.        "----响应时间戳:${realTime};发送时间戳:${__P(sendTime)}";  
17.        }  
18.}else{  
19.    Failure = true;  
20.    FailureMessage = "有响应,但编码错乱";  
21.    }  

第一行的 r e a l T i m e 是 响 应 结 果 中 获 取 到 的 实 际 时 间 , 第 四 行 的 {realTime}是响应结果中获取到的实际时间,第四行的 realTime{realCode}是获取到的时间格式,第四行的{__P(sendCode)}是另外一个线程内自定义的时间格式,第五行的${__P(sendTime)}是另外一个线程内自定义的发送时间。
Beanshell断言中Failure取true,代表发现错误,预期结果与实际结果不符;Failure取false,代表预期结果和实际结果相同;FailureMessage是输出的错误信息。
上述代码的意思为:先判断是否提取到了真实响应时间,若没提取到,代表请求失败了。若提取到,则判断时间格式是否正确。若格式正确则比较发送时间和响应时间是否大于5秒。
还是以登录为例,若数据库中正确的帐号密码是“zhangsan”,“123456”。发送登录请求,输入正确的帐号密码,请求成功,响应结果如下
在这里插入图片描述
此时我们可以提取errno为0进行beanshell断言。
若发送请求时,给出了错误的帐号密码,响应结果如下
在这里插入图片描述
此时我们可以根据errno为2000进行beanshell断言,并同时判断提示信息errmsg内容是否正确。断言方式需要灵活选择,尽量直接使用jmeter提供的断言方法,减少开发成本,最后选择beanshell断言。接口测试最重要的部分就是断言,一个没有断言的自动化接口测试脚本,其测试结果毫无意义。

五、集成到jenkins

Jmeter图形化页面进行脚本编写,调试,相当方便。为了提高运行速度,建议使用命令行模式运行脚本。
Jenkins中,创建一个自由风格的软件项目。
在这里插入图片描述
若是需要远程节点运行,在general中勾选“限制项目的运行节点”,如何添加远程节点,已经在本系列的第一篇中详细介绍过了。我这里的jmeter的脚本,都是基于图形化界面开发的,所以不需要进行源码管理。定时每周1到周6,中午12点30分运行一次。
在这里插入图片描述
在这里插入图片描述

当前运行环境是windows环境,所以用的是批处理命令。若是linux就使用shell命令。Jmeter的命令行模式运行的一些命令,可以在官方网站上查看介绍,具体网站是:https://jmeter.apache.org英语不好的,可以使用google浏览器,直接可以将英文网站翻译成中文网站。
在这里插入图片描述

放开样式权限(系列二中已经介绍过)
Groovy Script:System.setProperty(“hudson.model.DirectoryBrowserSupport.CSP”, “”)
设置在线查阅测试报告(系列二中已经介绍过)
Publish HTML reports
将测试结果发送到指定邮箱(系列二中已经介绍过)
Editable Email Notification
在这里插入图片描述
创建完成后,保存。构建失败可以在控制台中查看失败原因,重新调试程序。
在这里插入图片描述
在这里插入图片描述
构建成功可以在点击html report在线查看运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值