在性能测试领域,Apache JMeter作为一款功能强大且灵活的工具,被广泛应用于模拟各种用户行为和负载场景。其核心优势之一在于丰富的逻辑控制器,这些控制器允许测试人员以高度可定制的方式编排测试流程,从而更真实地反映生产环境中的复杂交互和条件逻辑。本文将详细探讨JMeter中的关键逻辑控制器,包括它们的定义、作用、工作原理以及实际应用示例,旨在帮助读者掌握如何利用这些工具设计高效、复杂的测试场景。
JMeter逻辑控制器概述
JMeter的逻辑控制器(Logic Controllers)是用于组织和管理测试计划中的采样器(Sampler)执行顺序和逻辑的核心组件。通过使用逻辑控制器,可以将多个采样器组合成一个有逻辑的执行单元,实现如条件判断、循环、事务管理等功能。合理运用逻辑控制器,不仅能够简化测试脚本的结构,还能提高测试的可维护性和可读性。
核心逻辑控制器详解
1. Simple Controller(简单控制器)
定义与作用:Simple Controller是最基本的逻辑控制器,它按照元素在HashTree中的顺序依次执行子元素。主要用于将多个相关的采样器或控制器组合在一起,以便统一管理和执行。
工作原理:Simple Controller会递归遍历其子节点,并按照顺序执行每个子节点。如果子节点是另一个控制器,它会进一步递归执行该控制器的子节点。
应用场景:适用于简单的线性测试场景,例如依次执行一系列HTTP请求或数据库操作。通过将相关操作放在同一个控制器下,可以更好地组织和管理测试计划。
2. Loop Controller(循环控制器)
定义与作用:Loop Controller用于控制其子元素的循环执行次数。它可以指定固定的循环次数,或者基于条件进行无限循环,直到手动停止。
工作原理:根据设置的循环次数或条件表达式,重复执行其子元素。每次循环开始时,都会重置所有变量和计数器,确保每次循环都是独立的。支持嵌套循环,即在一个循环内再嵌套另一个循环。
配置与使用:
- 循环次数:可以通过GUI界面设置固定的循环次数,或使用变量来动态控制。
- infinite:表示⼀直循环下去。
- 如果同时设置了线程组的循环次数和循环控制器的循环次数,那循环控制器的⼦节点运⾏的次数为两个数值相乘的结果。
应用场景:
- 模拟多次重复的操作,如连续登录、数据上传等。
- 性能测试中的压力测试,通过不断增加循环次数来评估系统在高负载下的表现。
- 与其他控制器结合使用,构建复杂的测试场景,如在循环中嵌套条件判断或事务控制。
3. If Controller(条件控制器)
定义与作用:If Controller用于根据指定的条件表达式来判断是否执行其子元素。只有当条件表达式的结果为真时,才会执行子元素;否则跳过。
工作原理:If Controller会根据设置的条件表达式来评估是否执行其子元素。条件表达式可以使用JMeter提供的函数和变量来构建,支持多种逻辑运算符和关系运算符。
配置与使用:
- 条件表达式:在“Condition”字段中填写条件表达式,如
${JMeterThreadNum} == 1
表示仅当线程编号为1时才执行子元素。 - 忽略标志:勾选“Ignore Condition”后,无论条件是否满足,都会执行子元素。这通常用于调试或临时绕过条件判断。
应用场景:
- 根据不同的用户角色执行不同的操作流程。
- 根据响应数据中的特定值来决定后续的测试步骤。
- 模拟不同条件下的用户行为,如网络延迟、错误处理等。
4. While Controller(循环控制器)
定义与作用:While Controller用于在满足特定条件的情况下重复执行其子元素。它会不断检查条件表达式的值,直到条件不再满足为止。
工作原理:While Controller会根据设置的条件表达式来评估是否继续执行其子元素。只要条件表达式的结果为真,就会一直执行子元素;一旦条件为假,就停止执行并退出循环。
配置与使用:
- 条件表达式:在“Condition”字段中填写条件表达式,如
${__jexl3(vars.get("count"),lt,5)}
表示当变量count
的值小于5时继续循环。 - 最大迭代次数:为了防止无限循环导致测试无法终止,可以设置最大迭代次数。当达到最大次数时,即使条件仍然满足也会强制退出循环。
应用场景:
- 模拟持续的用户操作或等待某个事件的发生。
- 压力测试中逐步增加负载直到系统崩溃或达到预定的性能指标。
- 与其他控制器结合使用构建复杂的测试场景如在循环中嵌套条件判断或事务控制等。
5. Transaction Controller(事务控制器)
定义与作用:Transaction Controller用于标记一个事务的边界。它可以将多个采样器组合成一个事务并生成关于该事务的性能指标报告如响应时间、成功率等。
工作原理:Transaction Controller会在其子元素执行之前和之后生成两个时间戳分别表示事务的开始时间和结束时间然后计算这两个时间戳之间的差值作为事务的持续时间此外它还会自动生成关于该事务的性能指标报告如平均响应时间、吞吐量等。
配置与使用:
- 名称:为事务控制器指定一个有意义的名称以便在报告中识别不同的事务。
- 注释:添加注释以描述事务的目的和包含的操作有助于提高测试脚本的可读性和维护性。
- 忽略思考时间:勾选此选项后在计算事务的持续时间时会忽略采样器之间的思考时间从而使事务时间更加准确。
应用场景:
- 标记关键的业务流程或用户操作如登录、购物车结算等以便对这些流程进行单独的性能分析和优化。
- 结合Assertions(断言)验证事务的响应数据是否正确以满足业务需求和质量标准。
QPS or TPS:
特性 | QPS (Queries Per Second) | TPS (Transactions Per Second) |
---|---|---|
定义 | 每秒钟处理完请求的次数 | 每秒钟处理完的事务次数 |
关注点 | 系统处理请求的能力 | 系统整体事务处理能力 |
应用场景 | API性能评估、Web服务性能测试 | 系统性能评估、业务流程处理能力 |
衡量指标 | 每秒完成的请求数量 | 每秒完成的事务数量 |
影响因素 | 服务器硬件配置、网络延迟、请求复杂度等 | 事务复杂度、并发用户数、系统架构等 |
优化方式 | 提高服务器性能、优化代码逻辑、使用缓存等 | 优化事务逻辑、提高系统并发处理能力、负载均衡等 |
示例 | 一个API接口在高并发下每秒能处理多少个请求 | 一个电商网站的下单操作涉及多个步骤,每个步骤都是一个事务,因此TPS较低时不一定代表系统性能差 |
这个表格展示了QPS和TPS的主要区别和联系。如果你有其他问题或需要进一步的解释,请随时告诉我。
6. Throughput Controller(吞吐量控制器)
定义与作用:Throughput Controller用于控制每秒执行的请求数(吞吐量)。它可以根据需要模拟不同的负载条件以评估系统在不同负载下的性能表现。
工作原理:Throughput Controller会根据设置的最大吞吐量来限制每秒执行的请求数当达到最大吞吐量时它会暂停执行新的请求直到有空闲资源可用为止此外它还支持动态调整吞吐量以适应变化的负载情况。
配置与使用:
- 最大吞吐量:设置每秒允许的最大请求数可以是固定的数值或基于变量的表达式。
- based on:
-
执行百分比 (Percent Executions):
按照设定的百分比来执行子元件。例如,设置50%表示在一半的迭代中执行。
该模式下,吞吐量控制器之间彼此不会影响,且Per User参数不生效。 -
总执行次数 (Total Executions):
按照设定的总次数来执行子元件。例如,设置10次表示子元件会执行10次。
如果勾选了Per User,每个线程会单独计算执行频率;否则,所有线程统一计算执行频率。
当吞吐量控制器的吞吐量之和大于线程组的总迭代次数时,以线程组迭代次数为准。
-
- 启动延迟:设置从测试开始到控制器生效之间的初始等待时间以便让系统有时间预热或完成其他准备工作。
- 结束延迟:设置从控制器停止到测试结束之间的等待时间以便观察系统在负载变化后的恢复情况。
应用场景:
- 模拟不同负载条件下的系统行为如逐渐增加负载直到系统达到最大容量或崩溃。
- 评估系统在高并发访问下的稳定性和性能表现。
- 与其他控制器结合使用构建复杂的测试场景如在循环中嵌套吞吐量控制以模拟突发流量等。
7. Once Only Controller(仅一次控制器)
定义与作用:Once Only Controller用于确保某个测试元素在整个测试过程中只执行一次无论它在测试计划中出现多少次或者被多少个线程调用。
工作原理:Once Only Controller会记录已经执行过的子元素的状态信息当再次遇到相同的子元素时它会检查状态信息并决定是否跳过该子元素如果子元素尚未执行过则正常执行;如果已经执行过则跳过执行。
配置与使用:
- 名称:为仅一次控制器指定一个有意义的名称以便在报告中识别不同的操作。
- 注释:添加注释以描述操作的目的和包含的步骤有助于提高测试脚本的可读性和维护性。
应用场景:
- 确保某些初始化操作或清理操作只执行一次如数据库连接的建立和关闭、缓存的预加载等。
- 防止在循环或条件判断中重复执行相同的操作以提高测试效率和准确性。
8. Interleave Controller(交替控制器)
定义与作用:Interleave Controller用于交替执行多个采样器或控制器它可以模拟多线程环境下的并发操作以确保每个线程按顺序执行不同的操作序列。
工作原理:Interleave Controller会根据设置的交替顺序依次执行其子元素每次选择一个子元素执行然后切换到下一个子元素继续执行直到所有子元素都被执行完一次为止然后重新开始循环。此外它还支持嵌套交替执行即在一个交替序列内部再嵌套另一个交替序列。
配置与使用:
- 交替顺序:设置子元素的执行顺序可以是固定的顺序或基于变量的动态顺序。
- 组大小:设置同时执行的子元素数量以便模拟不同的并发级别。
- 循环次数:设置交替序列的重复次数以便模拟长时间的并发操作或达到预定的性能指标。
应用场景:
- 模拟多线程环境下的并发访问如多个用户同时操作同一个功能模块。
- 评估系统在高并发下的互斥性和数据一致性问题。
- 与其他控制器结合使用构建复杂的并发测试场景如在交替执行中嵌套循环或条件判断等。
9. ForEach Controller(ForEach循环控制器)
定义与作用:ForEach Controller用于对一个集合中的每个元素进行迭代处理它可以遍历数组、列表或其他可迭代的数据结构并对每个元素执行指定的操作。
工作原理:ForEach Controller会根据设置的输入变量和起始索引来遍历集合中的每个元素每次迭代时都会将当前元素赋值给指定的引用变量然后执行其子元素。迭代完成后可以更新输入变量的值以便下次迭代使用新的元素值。此外它还支持嵌套迭代即在一个集合内部再嵌套另一个集合的迭代处理。
配置与使用:
- 输入变量前缀:设置要遍历的集合的名称可以是用户定义的变量或CSV文件中的列名等。
- 循环变量下标起点和终点:设置集合的起始索引和结束索引以便控制迭代的范围和次数。如果不设置终点则表示遍历整个集合的所有元素直到手动停止迭代过程为止。(注意:这里的起点是从0开始计数的)
- 引用变量名称:设置一个变量名用于存储当前迭代的元素值以便在子元素中使用该值作为参数传递数据等操作。(注意:这里的引用变量名称也是自定义的一个变量名而不是系统内置的变量名如${varName})
- 添加按钮:点击此按钮可以添加新的子元素到ForEach Controller中以便对每个迭代的元素执行指定的操作。(注意:这里添加的是具体的采样器或控制器而不是直接添加变量值本身哦!)
应用场景:
- 批量处理数据如导入/导出大量记录、更新数据库中的多条记录等操作时可以使用ForEach Controller来简化测试脚本的编写和维护工作。
- 模拟用户的连续操作如浏览商品列表、选择多个商品加入购物车等场景时可以使用ForEach Controller来遍历商品集合并对每个商品执行相应的操作如查看详情页面、添加到购物车等。(注意:这里需要配合其他控件如Counter或CSV Data Set来实现动态参数化的功能哦!)
- 与其他控件结合使用构建复杂的数据处理流程如在遍历过程中嵌套条件判断或事务控制等以满足不同的测试需求和场景要求。(注意:这里需要注意的是ForEach Controller本身的局限性——它只能处理一维数组结构的数据对于多维数组或复杂对象结构的处理能力有限因此在实际使用中可能需要结合其他控件如JSR223 Sampler或Beanshell Sampler来进行扩展和补充哦!)
10. Random Controller定义与作用
定义与作用:Random Controller用于在每次循环中随机执行其子项,帮助模拟真实情况。通过随机选择子项,可以更真实地反映用户行为的多样性和不确定性。
参数详解:
- Ignore sub-controller blocks:勾选后,随机控制下的子控制器中的多个子项只会被执行一个;不勾选时,交替执行时,节点下次一级每个取样器、逻辑控制器都认为是一个单独子节点来交替执行。
具体实例:
- 不勾选忽略子控制器模块的例子:我们在随机控制器外层包一个循环控制器,设置循环次数是3次,随机控制器下有三个取样器+一个简单控制器(简单控制器下有两个取样器)。运行结果如下:确定要放弃本次机会?
应用场景:
- Random Controller广泛应用于需要模拟用户行为多样性的场景,如容量测试、负载测试等。通过随机执行不同的操作路径,可以更准确地评估系统在不同负载条件下的表现。
11.Module Controller
定义与作用:Module Controller用于在JMeter中实现测试计划的模块化,允许用户创建可重用的测试片段。通过引用这些片段,可以在运行时动态替换当前测试计划的部分内容,从而提高测试脚本的复用性和维护性。
参数详解:
- Module Controller提供了控制和引用测试片段的功能。用户可以在模块控制器中选择要运行的测试片段,并在运行时将其替换为当前测试计划的对应部分,从而实现灵活的测试管理。
具体实例:
- 创建一个登录测试片段和一个注册测试片段,每个片段包含相应的请求和逻辑。通过Module Controller,可以在同一个线程组中灵活调用这两个片段,根据需要执行不同的测试场景。
应用场景:
- Module Controller适用于需要频繁复用测试逻辑的场景,如API测试、功能测试等。通过将常用操作封装成模块,可以快速构建复杂的测试方案,提高测试效率和覆盖率。
12.Include Controller定义与作用
定义与作用:Include Controller用于导入外部的JMX文件,实现测试计划的模块化。通过引用外部片段,可以简化复杂脚本的管理和维护,提高测试用例的复用性和灵活性。
参数详解:
- Name:控制器名称,可以根据需求自定义。Comments:注释,描述控制器在业务中的作用。Include Test Plan:导入测试计划,被导入的测试计划不能包含线程组,只能包含控制器及其子元件。
具体实例:
- 创建一个登录成功的请求和一个登录失败的请求,保存为一个测试片段。在新的测试计划中,使用Include Controller引入该测试片段,并添加监听器查看执行结果。
应用场景:
Include Controller适用于需要频繁复用测试逻辑的场景,如API测试和功能测试。通过将常用操作封装成模块,可以快速构建复杂的测试方案,提高测试效率和覆盖率。
总结与展望
随着技术的不断发展和用户需求的变化,JMeter的逻辑控制器也在不断进化和完善。未来,我们可以期待更多功能强大且灵活的新控制器的出现,以进一步提升性能测试的效率和精准度。同时,对于现有的控制器,也将持续进行优化和改进,以提高其稳定性和易用性。因此,作为性能测试工程师,我们需要不断学习和掌握最新的技术和工具,以应对日益复杂多变的性能测试挑战。