引子
先看一下这个例子,测试计划“进入考场”下面有一个线程组,线程组下面有 3 个 HTTP 请求,分别是学生登录、考场 token和进入房间:
它们的处理逻辑是:
-
学生登录后,在响应中返回了登录后的 token,使用正则表达式提取器,提取登录 token
-
在登录以后,把登录 token 作为 header,去请求“考场token”这个接口,请求后的响应中,返回了考场 token,使用正则表达式提取,下图是“考场token”请求的 header,使用了 HTTP Header 管理器:
拿到考场 token 以后,把考场 token 作为 header,去请求“进入房间”接口,下图是“进入房间”请求的 header,Value定义的是 ${exam_token},就是考场 token,这个 token 是从第 2 个请求“考场token”的响应中,使用正则表达式提取出来的:
回顾一下,首先登陆,登陆后获取token,然后再获取考场token,最后进入房间。这个例子的问题就在于,第 2 个请求和第 3 个请求,都设置了 header,这 2 个 HTTP Header Manager 能按我们想的去工作吗?
运行顺序与作用域
运行顺序
先了解一下 JMeter 元件的运行顺序。JMeter 根据 2 个维度来决定元件的运行顺序,第 1 个维度是从上往下,第 2 个维度是元件类型。
从上往下,指的是从根节点->父节点->子节点->叶子节点。
元件类型,分为 3 类:
- 线程组、逻辑控制器。
- 取样器。
- 配置元件、前置处理器、定时器、后置处理器、断言、监听器。
最后这六个元件类型,都是为取样器服务的。它们的运行顺序如下:
-
配置元件(如果存在)
-
前置处理器(如果存在)
-
定时器(如果存在)
-
取样器(如果存在)
-
后置处理器(如果存在且取样器的结果不为空)
-
断言(如果存在且取样器的结果不为空)
-
监听器(如果存在且取样器的结果不为空)
我总结一下加强理解。假设我们新建了 1 个线程,想用这个线程去发请求。
首先是初始化配置,比如参数化、设置 Header、Cookie 等,配置元件。
接着可能需要给线程加点参数,比如用户参数,会用到前置处理器。
然后在发送请求前可能会等待一段时间,添加定时器。
准备好以后,就可以发送请求了,也就是取样器。
如果取样器什么数据也没有返回,那么就可以直接退出了。
如果返回了数据,使用后置处理器,比如正则表达式提取器,提取想要的数据。
提取之后还有要做验证,断言一把。
测试运行的怎么样呢,用监听器看一看。
示例
再结合示例感受一下,请看以下测试计划,添加了 1 个 线程组,包含 3 个 取样器(HTTP Request 1 2 3):
JMeter 会按以下步骤运行:
- 线程组(如果有多个线程组可以在测试计划设置是顺序执行还是同时执行)
- 简单控制器(父节点)
- HTTP Cookie 管理器(配置元件)
- 用户参数(前置处理器)
- Synchronizing Timer(定时器)
- HTTP 请求 1(取样器)
- 正则表达式提取器(后置处理器)
- 响应断言(断言)
- HTTP Cookie 管理器(配置元件)
- 用户参数(前置处理器)
- Synchronizing Timer(定时器)
- HTTP 请求 2(取样器)
- 正则表达式提取器(后置处理器)
- 响应断言(断言)
- HTTP 请求 3(取样器)
- 察看结果树(严格来讲是与第 6 步并行,也就是取样器之后)
作用域
第 9 ~ 14 步我用黑色斜体加粗了,因为从图中的位置来看,“HTTP 请求 2”,前后并没有元件,但是也被作用上了。
这是因为它们具有相同的作用域,在 JMeter 中,同一层级的元件具有相同的作用域。
示例中,添加了一个简单控制器,然后在下级添加了配置元件、前置处理器、定时器、后置处理器、断言,和 2 个取样器(HTTP Request 1 2 )。
简单控制器是一个执行单元,本身没有内容,它的作用是把元件进行分组运行:
所以简单控制器下面的这些同级元件,作用域相同,既会作用于 HTTP Request 1,也会作用于 HTTP Request 2。
配置元件、前置处理器、定时器、后置处理器、断言、监听器,这六个元件类型,会作用到范围内的所有取样器。
层级
在 JMeter 中,上级的作用域包含下级的作用域。
但是下级是不能作用到上级的。
比如示例中的 HTTP Request 3,和简单控制器是平级,那么简单控制器下级的元件,是不会作用到 HTTP Request 3 的。
使用建议
再看看开头的例子:
有 3 个取样器,用户自定义变量和 CSV Data Set Config,都是配置元件,跟取样器同级,会同时作用到这 3 个取样器上面。
HTTP Header Manager 也是配置元件,不会作用到学生登录取样器,因为根据从上往下的维度,它们都位于学生登录取样器之后。
图中有 2 个 HTTP Header Manager,你可能会认为它们会分别执行,实际上它们会一起执行!
在同一执行单元中,如果相同类型的元件有多个,会被当做一个一起执行。
我把第 2 个 HTTP Header Manager 稍微改了一下,可以看得很明显:
考场token的请求,在目录树中是第 2 个,但是从结果来看,它的 header,被添加上了我在后面第 3 个请求设置的 header了。
这个结果显然不是想要的。
所以为了避免混乱,建议在使用 JMeter 添加元件的时候,一是根据先后顺序,从上往下合理的放置元件的顺序。二是对于配置元件、前置处理器、定时器、后置处理器、断言这六类元件,因为它们都是为取样器服务的,如果只想作用于单个取样器,最好是放在这个取样器的下级,以避免由于同一作用域相互作用,导致意想不到的结果。
这个例子把 HTTP Header Manager 分别放到各自的取样器下级,就能按设想运行起来了:
简要回顾
本文首先引入了我工作中碰到的问题,接着结合示例讲解了运行顺序、作用域和层级,搞懂了 JMeter 目录树是怎么运行的,最后回到开头的例子进行了结果分析,给出了在使用时的两条建议。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/2663.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...