接口测试04-逻辑控制器
现有一电商网站,需要测试该程序中的下订单这一业务实现,该业务可能由多个步骤组成:
1.首先需要完成登录操作(分支)
2.然后需要查询商品,
3.再将商品加入购物车,(循环)
4.再进入购物车,
5.最后,执行支付操作(访问支付接口时,需要获取步骤4购物车中的支付金额 = 步骤4和5接口之间需要数据传递)
....
上述每一步都有对应的接口实现
显然的,测试接口业务时,不能也不是测试单个接口了,是将若干接口串联在一起集成测试,而不同接口在组织衔接时,会遇到执行逻辑与数据传递的问题,那么怎样实现接口的逻辑组织与数据传递呢?
JMeter 提供了专门的解决方案:接口间的逻辑组织可以通过逻辑控制器实现,而不同接口间的数据传输可以通过关联实现
1.接口业务测试之逻辑控制器
1.1 概念
逻辑控制器: 控制测试计划中取样器的执行顺序的组件实现
类似于 Python 的流程控制语句(控制代码的执行顺序)
执行顺序: 顺序执行 + 分支(if) + 循环(while + for)
1.2 作用
接口业务测试时,用于控制不同接口的执行逻辑
1.3 实现
3.1 分类
-
如果(if)控制器 = 分支
-
ForEach控制器 = 循环(迭代控制器)
-
循环控制器 = 循环(控制循环次数)
3.2 实现
需求1:测试计划中定义一个 http 请求访问传智播客官网,但是该请求不是无条件执行的,声明一个用户定义的变量,如果变量是 itcast 才执行,否则就不执行
实现:
-
搭框架(测试计划、线程组、查看结果树....),添加一个用户定义的变量,存储数据(可能是 itcast)
-
核心: 添加如果(if)控制器组件,判断用户定义的变量是否是 itcast,如果是,需要执行取样器(子级)
-
如果是 itcast, 取样器执行
否则,取样器不执行
PS: 控制器与取样器必须是父子级关系
需求2:有一组关键字 [hello,python,测试] (使用用户定义的变量存储)要依次取出,并在百度搜索
实现:
-
搭框架(测试计划、线程组、查看结果树....),使用用户定义的变量存储3个数据
2
3.
PS: 控制器与取样器必须是父子级关系
需求3:循环访问学生管理系统10次
-
搭框架(测试计划、线程组、查看结果树 .....)
-
核心: 添加循环控制器控制执行次数,子级添加取样器
问题:可以配置线程组的循环次数,二者实现有什么区别?
-
线程组的循环次数控制组内所有取样器的执行次数(作用域大)
-
循环控制器可以控制组内某个或某些取样器的执行次数(作用域小,但是控制精度更高)
2.1 概念
关联: 上一个请求响应的结果作为下一个请求提交的参数(在不同请求之间执行数据传递)
2.2 作用
接口业务测试中,频繁的是使用到关联
-
购物车实现
测试支付功能时,至少要访问两个接口(购物车查看 + 支付),从购物车查看接口中,获取响应的订单总金额信息,然后将该金额作为参数提交给支付接口
-
今日头条回帖功能
回帖时,需要提交回复信息以及被回复的主贴的 ID,主贴的 ID 可以通过查看主贴信息来获取,测试中:
先访问主贴信息,从响应结果中提取主贴的 ID,然后再作为参数提交给回复接口
......
2.3 实现
2.3.1需求:两个http请求,请求A访问传智播客官网,请求B访问百度 ,请求A将传智播客官网源码中的 title 标签的值取出,传递给请求B,在请求B中作为关键字搜索这个 title 值
-
搭框架(测试计划、线程组、查看结果....),两个取样器,分别访问 itcast.cn 和 baidu.com
-
核心提取: 怎么从 itcast.cn(上一个请求)提取 title === XPath 提取器
3.
-
调用格式: ${变量名}
2.3.2 需求:两个请求,请时求A查询所有学院信息,请求B访问百度,从请求A中提取出第一个学院的学院名称,再在请求B上搜索
-
搭框架(测试计划、线程组、查看结果....),两个取样器,分别访问 学生管理系统 和 baidu.com
-
核心提取: 怎么从 学院访问(上一个请求)提取第一个学院名称 === 正则表达式 提取器
-
调用格式: ${变量名}
2.4 XPath 与 正则表达式 比较
-
相同点: 功能类似,都可以在响应结果中定位并提取数据
-
不同点: 使用范围有差异
XPath: 只能应用于标签文档
正则表达式: 既可以应用于文本文档,又可以应用于标签文档(作用范围更广)
-
建议: 如果是标签文档,建议使用 XPath,否则就是以正则表达式
2.5 跨线程组关联(进阶)
需求:在之前的案例基础上,将请求A和请求B设置进不同的线程组,且设置了线程组的执行顺序,可以保证 A先执行,B后执行,但是关联失败,为什么?怎样解决?
原因: 作用域问题
-
提取器提取结果并赋值给了变量,默认情况下,该变量作用域仅限于当前线程组
-
如果当前组内取样器调用变量,可以正常调用,但是如果其他线程组调用该变量,那么由于超出了作用域,会导致调用失败
解决: 扩大变量的作用域(变局部变量为全局变量)
-
将局部变量导出为全局变量(存入公共空间) == __setProperty()
另一个线程组,再从公共空间调用全局变量 == __Property()
测试计划 ---> 添加 ---> 非测试元件 ---> 属性显示
3.1 概念
性能测试: 模拟生产环境下各种场景(正常、峰值....),向服务器施加负载,然后查看性能指标是否符合预期
3.2 作用
1.技术选型
2.测试当前程序所能支持的最大负载
3.发现程序中性能瓶颈, 提高资源利用率
4.提升用户体验
.........
3.3 实现
3.3.1.接口性能测试定时器之同步定时器
需求1:同一时刻100 个同学去访问学生管理系统的查询所有学院信息功能,统计高并发情况下平均响应时间以及错误率
-
搭框架(测试计划、线程组、取样器、结果树....),将线程数设置成 100 模拟用户
-
核心: 怎么做到 100 个线程同时访问 === 需要添加组件: 同步定时器(又称之为集合点组件)
阶段1: 启动所有的线程,并不马上执行
阶段2: 所有线程都启动完毕,才同时执行
3.3.2接口性能测试定时器之常量吞吐定时器
需求2:一个用户以 20QPS ( == 20 次/s) 的频率访问学生管理系统服务器,持续15秒,统计服务器的平均响应时间
QPS == Query Per Second == 每秒查询数(查询率)
-
搭框架(测试计划、线程组、取样器、查看结果树、聚合报告),将循环次数设置成 300
循环次数 = 访问频率 * 持续时间
-
核心: 设置访问频率 == 常量吞吐定时器
4.1 概念
分布式: 多台测试机协作以集群的方式完成测试任务
4.2 作用
场景: 性能测试时,需要模拟大量甚至海量的虚拟用户,单台测试机由于性能制约,启动的线程数有限,此时就可以使用分布式,可以将所有的线程任务平均分配给分布式集群中的每台测试机,每台测试机只需要启动部分线程即可
4.3 实现
4.3.1 基本架构(重点)