线程组

线程组作为JMeter测试计划的核心组件之一,对于模拟并发用户的行为至关重要。线程组元件是整个测试计划的入口,所有的取样器和控制器必须放置在线程组下。

可以将线程组视为一个虚拟用户池,其中每个线程可被理解为一个虚拟用户,多个虚拟用户同时执行相同的一批任务。

在这个虚拟用户池中,每个线程之间是相互隔离且互不影响的。每个线程的执行过程中,操作的变量不会对其他线程的变量值产生影响。

线程组的关键任务之一是定义并发用户的行为,包括设置线程数、循环次数、启动延迟等关键参数。通过适当配置线程组,测试人员可以模拟多用户在系统中同时执行任务的场景,从而评估系统的性能和稳定性。

通过灵活使用setup线程组、线程组、tearDown线程组、开放模型线程组,配置前置操作、主要操作、后置操作,更能真实、详细的评估系统。

线程组分为四类:

  • 线程组
  • setUp线程组
  • tearDown线程组
  • 开放模型线程组

线程组、setUp线程组、tearDown线程组控制面板中的元素基本一致:

  • 名称、注释
  • 在取样器错误后执行的动作
  • 线程数
  • Ramp-Up时间
  • Same user on each iteration
  • 延迟创建线程直到需要(只有线程组有)
  • 调度器

开放模型线程组控制面板中的元素:

  • 名称、注释
  • 在取样器错误后执行的动作
  • 调度计划
  • 随机种子

执行顺序

在JMeter中,setUp线程组拥有最高的优先级,而tearDown线程组则具有最低的优先级。这一优先级关系可用表达式表示为:setUp线程组 > 线程组 = 开放模型线程组 > tearDown线程组

这意味着在测试计划执行过程中,setUp线程组将首先执行,其后是线程组开放模型线程组,最后执行tearDown线程组

通常情况下,setUp线程组用于在测试执行之前进行一些初始化工作,而tearDown线程组用于测试执行结束后的清理工作。

其他线程组在测试执行过程中按照它们在测试计划中的顺序执行。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup/', methods=['GET', 'POST'])
def threadgroup1():
sleep(3) # 接口设置了休眠三秒,即接口在接收到请求数据三秒后,返回响应数据。
return "我是响应"

示例Jmeter脚本

  • 测试计划中,分别添加tearDown线程组、线程组、setUp线程组

  • tearDown线程组、线程组、setUp线程组下分别添加HTTP请求取样器

    名称分别为:tearDown线程组线程组setUp线程组

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup1/

    请求方式:GET

  • 测试计划下添加查看结果树

演示内容

运行,查看结果树

可以观察到在2024-04-03 15:00:07 时,setUp线程组中的取样器发送了请求。

随后,在 2024-04-03 15:00:10 时,线程组中的请求取样器也发出了请求。

最后,在 2024-04-03 15:00:13时,tearDown线程组请求取样器发出了请求。

这与接口设置的休眠时间一致,表明 JMeter 先执行setUp线程组,随后执行线程组,最后执行 tearDown线程组 。即使脚本中的顺序不是这样。

Jmeter中线程组的执行顺序可以归纳为:setUp线程组 > 线程组 > 开放模型线程组 > tearDown线程组


线程数

线程组中的线程数指的是同时运行的虚拟用户数量。这个数量决定了你的测试将模拟多少个用户同时访问目标应用程序或服务。

在JMeter的线程组配置中,你可以根据你的需求来设置线程数,通常是根据你想要模拟的用户负载量和你的系统资源来决定的。

需要注意的是,线程数设置得太高可能会导致测试机器资源不足,影响测试结果的准确性;而设置得太低可能无法模拟真实的负载情况。因此,需要根据具体情况进行合理的设置。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup2/', methods=['GET', 'POST'])
def threadgroup1():
return "我是响应"

示例Jmeter脚本

  • 测试计划下,添加1个线程组

    线程数:3

  • 线程组下,添加HTTP请求取样器

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup2/

    请求方式:GET

  • 测试计划中,添加查看结果树

演示内容

运行,查看结果树

图中取样器结果中的Thread Name分别为线程组 1-1线程组 1-2线程组 1-3。这是因为线程组线程数值为3,Jmeter启功了3个线程,每个线程皆执行1次线程组

在Jmeter中1个线程就代表1个用户,现在就相当于3个用户一起执行线程组


循环次数

在JMeter中,循环次数是指每个线程(即虚拟用户)执行其测试计划的次数。这个数量决定了你的测试将模拟用户访问目标应用程序或服务的次数。

在JMeter的线程组配置中,你可以根据你的需求来设置循环次数,通常是根据你想要模拟的用户访问上限值,如抽奖次数。

需要注意的是,循环次数设置得太高,特别设置循环次数为永远,可能会导致测试机器资源不足,影响测试结果的准确性;而设置得太低可能无法达到测试要求。因此,需要根据具体情况进行合理的设置。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup2/', methods=['GET', 'POST'])
def threadgroup1():
return "我是响应"

示例Jmeter脚本

  • 测试计划下,添加1个线程组

    循环次数:3

  • 线程组下,添加HTTP请求取样器

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup2/

    请求方式:GET

  • 测试计划中,添加查看结果树

演示内容

运行,查看结果树

图中取样器结果中的Thread Name皆为线程组 1-1。这是因为线程组循环次数值为3,Jmeter启功了1个线程,连续执行了3次线程组

在Jmeter中1个线程就代表1个用户,现在就相当于1个用户执行了3次线程组


取样器错误后执行的动作

在JMeter中,取样器(Sampler)是用于模拟用户请求发送到目标服务器的组件,例如HTTP请求、FTP请求等。当取样器执行过程中出现错误时,可以通过配置相应的动作来处理这些错误。以下是一些处理取样器错误时,线程组中常见方式:

  • 停止测试
  • 立即停止测试
  • 停止线程
  • 启动下一进程循环
  • 继续

通过合理配置这些错误处理方式,可以根据测试需求和场景来控制测试计划的行为,确保对错误有适当的响应和处理。


停止测试

设置取样器错误后执行的动作停止测试时,一旦任何一个取样器遇到错误,整个测试计划将会在所有当前正在执行的线程执行完毕后停止。这可以用于模拟在测试过程中发生重要错误或异常时的行为。

这种设置确保在测试执行中任何关键的错误都会导致测试的终止,以便进行及时的识别和处理。这对于模拟真实世界中的异常情况以及确保测试的准确性和可重复性都是非常重要的。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup3/', methods=['GET', 'POST'])
def threadgroup3():
if request.method == 'GET': # `错误请求`立即响应
return {'code': 200}
sleep(3) # 延长非`错误请求`的请求时间
return {'code': 200} # `非错误请求`延迟响应

单线程组

示例Jmeter脚本
  • 测试计划下添加线程组

  • 线程组下添加2个HTTP 请求取样器

    名称:错误请求正确请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    正确请求的请求方式:POST

    错误请求的请求方式:GET

  • 错误请求取样器下添加响应断言

    值:1111

  • 测试计划中,添加查看结果树

演示内容

运行,查看结果树

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行。错误请求的结果报错后,因为设置取样器错误后执行的动作停止测试,同时没有其他正在执行的线程,Jmeter直接结束本次测试。

删除响应断言,再次运行

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行。因为错误请求的结果没有报错,会继续执行正确请求

多线程组

示例Jmeter脚本
  • 测试计划下添加2个线程组

    名称:线程组1线程组2

  • 线程组1下添加HTTP 请求取样器

    名称:错误请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    请求方式:GET

  • 线程组2下添加2个HTTP 请求取样器

    名称:与错误请求并行的正确请求错误请求之后的正确请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    请求方式:POST

  • 错误请求取样器下添加响应断言

    值:1111

  • 错误请求之后的正确请求取样器下添加固定定时器(右键取样器-添加-定时器-固定定时器)

    线程延迟:3000

  • 测试计划中,添加查看结果树

固定定时器可以延迟取样器的执行时间,设置为3秒,可以确保错误请求之后的正确请求错误请求结束后执行。

演示内容

运行,查看结果树

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行,线程组一般并发执行的。错误请求的结果报错时,与错误请求并行的正确请求也正在执行,错误请求之后的正确请求还未执行。

因为设置取样器错误后执行的动作停止测试,待与错误请求并行的正确请求结束后不会执行错误请求之后的正确请求,Jmeter直接结束本次测试。

此时,测试计划中未勾选独立运行每个线程组

勾选独立运行每个线程组,再次运行

图中连续运行了5次,但是结果不符合预期。预期结果应该是不会执行线程组2,但是执行了。应该是Jmeter的一个BUG(或许是独立运行每个线程组的问题)。读者请谨慎使用。


立即停止测试

设置取样器错误后执行的动作立即停止测试时,当取样器在执行过程中遇到错误时,JMeter会立即停止当前运行的测试,不再执行任何后续的请求或操作。

这有助于保护应用程序免受可能导致问题的异常或错误的影响,并确保测试结果的准确性。

这种设置对于测试场景中的稳定性和可靠性非常重要,特别是在模拟并发用户或大负载情况下,能够及时发现问题并停止测试,有助于减少潜在的影响和损害。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup3/', methods=['GET', 'POST'])
def threadgroup3():
if request.method == 'GET': # `错误请求`立即响应
return {'code': 200}
sleep(3) # 延长非`错误请求`的请求时间
return {'code': 200} # `非错误请求`延迟响应

单线程组

示例Jmeter脚本
  • 测试计划下添加线程组

  • 线程组下添加2个HTTP 请求取样器

    名称:错误请求正确请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    正确请求的请求方式:POST

    错误请求的请求方式:GET

  • 错误请求取样器下添加响应断言

    值:1111

  • 测试计划中,添加查看结果树

演示内容

运行,查看结果树

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行。错误请求的结果报错后,因为设置取样器错误后执行的动作立即停止测试,Jmeter直接结束本次测试。

删除响应断言,再次运行

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行。因为错误请求的结果没有报错,会继续执行正确请求

多线程组

示例Jmeter脚本
  • 测试计划下添加2个线程组

    名称:线程组1线程组2

  • 线程组1下添加HTTP 请求取样器

    名称:错误请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    请求方式:GET

  • 线程组2下添加2个HTTP 请求取样器

    名称:与错误请求并行的正确请求错误请求之后的正确请求

    请求地址:HTTP://127.0.0.1:5000/api/ThreadGroup3/

    请求方式:POST

  • 错误请求取样器下添加响应断言

    值:1111

  • 错误请求之后的正确请求取样器下添加固定定时器(右键取样器-添加-定时器-固定定时器)

    线程延迟:3000

  • 测试计划中,添加查看结果树

固定定时器可以延迟取样器的执行时间,设置为3秒,可以确保错误请求之后的正确请求错误请求结束后执行。

演示内容

运行,查看结果树

图中连续请求了三次,结果是一致的。

取样器在线程组中一般是从上至下顺序执行,线程组一般并发执行的。错误请求的结果报错时,与错误请求并行的正确请求也正在执行,错误请求之后的正确请求还未执行。

因为设置取样器错误后执行的动作立即停止测试,不会等待与错误请求并行的正确请求结束,Jmeter会直接结束本次测试,因此与错误请求并行的正确请求的响应结果提示 Socket 关闭异常。

此时,测试计划中未勾选独立运行每个线程组

勾选独立运行每个线程组,再次运行

图中连续运行了2次,但是结果不符合预期。预期结果应该是不会执行线程组2,但是执行了。应该是Jmeter的一个BUG(或许是独立运行每个线程组的问题)。读者请谨慎使用。

提示

本文示例接口源代码可从前言中下载。


Jmeter线程组-上的更多相关文章

  1. 【转】关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念

    关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念 笔者是个刚刚踏入压力测试领域不到2个月的小菜,这里分享一下线程组中3个参数之间关系的个人见解,不喜请!喷!,望大家 ...

  2. 关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念

    关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念 笔者是个刚刚踏入压力测试领域不到2个月的小菜,这里分享一下线程组中3个参数之间关系的个人见解,不喜请!喷!,望大家 ...

  3. JMeter线程组编辑区揭秘

    线程组编辑区如下: 有点复杂,但是慢慢看下来,还是比较容易理解. Name 带有业务含义的名字. Comments 线程组的备注说明. Action to be taken after a Sampl ...

  4. Jmeter线程组间传递参数

    现在做测试和以前不太一样了,以前只要站在一个用户的角度做端到端的UI测试就可以了,现在不会做接口测试,出去都不好意思和别人打招呼.那提到接口测试,就不得不提一下接口测试利器Jmeter,大家也都知道, ...

  5. Jmeter线程组设置

    添加线程组:右键测试计划->添加->Threads->线程组 左侧树形标签栏中,显示标签信息. 选中线程组,右侧内容栏中显示线程组的相关信息. 名称:可以给线程组设置一个个性化的命名 ...

  6. jmeter线程组之间传递参数

    JMeter 变量作用域局限于所属线程.这样设计是经过深思熟虑的,目的是让测试线程能够独立运转.有时候用户可能需要在不同线程间(可能属于同一个线程组,也可能不属于同一个线程组)传递变量. 其中一种方法 ...

  7. JMeter 线程组之ConcurrencyThreadGroup介绍

    线程组之ConcurrencyThreadGroup by:授客 QQ:1033553122 测试环境 apache-jmeter-3.2 jmeter-plugins-manager-1.3.jar ...

  8. JMeter 线程组之Stepping Thread Group插件介绍

    线程组之Stepping Thread Group插件介绍   by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13   插件: https://jmeter-plu ...

  9. jmeter线程组之间传参

    背景介绍: 使用jmeter做登录和搜索接口的测试: 登录接口请求头为:Content-Type: application/x-www-form-urlencoded; charset=UTF-8 搜 ...

  10. jmeter线程组介绍

    Jmeter中的测试计划是一直有的,但可以在右侧修改名字,要开始做具体测试设计前,都需要在测试计划下边添加一个线程组,添加路径为鼠标捕获测试计划后,点击鼠标右键->添加->Threads( ...

随机推荐

  1. 信捷电气 - C++工程师面试题(社招:3-5年工作经验)

    1. char i = 1; printf("%d",i);    // char字节用printf以整数型打印出来 2. int (*a[10])int a[10]是函数指针数组 ...

  2. 【libGDX】Mesh立方体贴图(6张图)

    1 前言 ​ 本文通过一个立方体贴图的例子,讲解三维纹理贴图的应用,案例中使用 6 张不同的图片给立方体贴图,图片如下. ​ 读者如果对 libGDX 不太熟悉,请回顾以下内容. 使用Mesh绘制三角 ...

  3. SpringBoot与Thymeleaf入门级操作

    使用Thymeleaf 三大理由: 简洁漂亮 容易理解 完美支持HTML5 使用浏览器直接打开页面 不新增标签 只需增强属性 学习目标 快速掌握Thymeleaf的基本使用:五大基础语法,常用内置对象 ...

  4. 第131篇:如何上传一个npm包

    好家伙, NPM的全称是Node Package Manager,是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准.  NPM是世界上最大的软件注册表. 1.首先我们 ...

  5. gorm整理

    目录 1. 约定 2. 结构体标签 3. 创建记录 4. 更新 5.删除 6. 查询 7.关联 8.链式操作 9.范围 10.多个立即执行方法的注意事项 11.错误处理 12.钩子 13.事务 14. ...

  6. 智联招聘基于 Nebula Graph 的推荐实践分享

    本文首发于 Nebula Graph Community 公众号 本文整理自智联招聘资深工程师李世明在「智联招聘推荐场景应用」的实践分享 搜索推荐架构 在讲具体的应用场景之前,我们先看下智联招聘搜索和 ...

  7. day02-自己实现Mybatis底层机制-01

    自己实现Mybatis底层机制-01 主要实现:封装SqlSession到执行器+Mapper接口和Mapper.xml+MapperBean+动态代理Mapper的方法 1.Mybatis整体架构分 ...

  8. terminate called after throwing an instance of 'std::regex_error'(C++11)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  9. 简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能

    前言 最近简单学了下Rust,以我这种菜鸟水平,没感受到什么安全.性能什么方面的优势,只觉得概念太多,编译各种报错.暂时也写不出来什么玩法,索性对比下各种学过的语言的性能.部分语言很早之前学过,很久不 ...

  10. Welcome to YARP - 3 负载均衡 (Load Balancing)

    目录 Welcome to YARP - 1.认识YARP并搭建反向代理服务 Welcome to YARP - 2.配置功能 2.1 - 配置文件(Configuration Files) 2.2 ...