vlambda博客
学习文章列表

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


自动化测试技术的火热除了表现在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了。


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


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] :第三本书

$..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,在设置全局变量的请求中,可以直接使用${token},前面的“allThreadUseToken”是全局变量名,可以随便起,自己记得住就行,最好做到见名知意。

“第一次登录需要设置手势密码”这个请求和登录请求在不同的线程组,所以无法直接使用${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.    }  

第一行的${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

将测试结果发送到指定邮箱(系列二中已经介绍过)


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


创建完成后,保存。构建失败可以在控制台中查看失败原因,重新调试程序。


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


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


构建成功可以在点击html report在线查看运行结果


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


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


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



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



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

推荐阅读

点击阅读☞

点击阅读☞

点击阅读☞

点击阅读☞

点击阅读☞

“阅读原文”一起来充电吧!