前言
在使用jmeter时,需要将前面使用的数据提取出来以便后续的使用,例如提取登录时的token设置全局变量给后续使用。根据条件是否进行后续操作,例如当登录成功时才设置token为全局变量。根据流程需要依赖前面的动态值,将动态值提取出来设置为全局变量,将设置的默认值替换为前面的动态值值才能进行操作,例如前面的某ID需要提起出来,然后通过jsr 223将此值赋给csv文件中的某个值。在此记录这两个代码组件。
beahshell组件是以java代码为基础的组件,JSR 223是可以根据各种编程语言来处理数据的组件。JSR 223也支持python。由于jmeter是以java为基础开发的应用,所以在执行beahshell组件时候的速度是比JSR 223+python更快。但是JSR223 + Java > BeanShell,由于本人主要使用python,所以主要介绍JSR 223和python脚本的使用。
JMeter中常用的内置对象
vars:JMeterVariables类的对象,它提供了一系列操作JMeter变量的方法,常用的方法有:
vars.get(String key):从JMeter中获得变量值
vars.getObject(),从JMeter中获得列表
vars.put(String key,String value):数据存到JMeter变量中,如果key存在就更新,不成在就创建一个变量。
props:Properties类的对象;操作JMeter属性,该变量引用了JMeter的配置信息,可以获取JMeter的属性。
props.get("language");注:language为属性名,在文件JMeter.properties中定义; #如果要提取列表得先用json.loads()序列化成python对象处理完后使用json.dumps()再变为json对象后设为全局变量
props.put("PROP1","1234"); 数据存到JMeter属性中,如果key存在就更新,不成在就创建一个属性。
prev:SampleResult类的对象;获取前面的取样器响应的信息,常用方法:
getResponseDataAsString():获取响应信息
getResponseCode():获取响应code
log:Logger`类的对象,提供了一系列的日志操作方法,常用的方法有:
log.info(“This is log info!”) #在Jmeter日志中可以查看此内容
核心区别总结
| 特性 | vars (JMeterVariables) | props (Properties) |
|---|---|---|
| 作用范围 | 当前线程组内 | 整个 JMeter 实例(所有线程组) |
| 生命周期 | 单个线程的生命周期 | JMeter 进程的生命周期 |
| 线程安全 | 线程隔离,线程安全 | 全局共享,需要同步 |
| 主要用途 | 线程内变量传递 | 全局配置、参数共享 |
| 数据类型 | 支持对象存储 | 主要是字符串 |
| 特性 | props.put() / props.get() | __P() / __setProperty() |
|---|---|---|
| 使用环境 | JSR223 脚本(Groovy/Jython/Java) | JMeter 函数(可在任何地方使用) |
| 语法 | 编程语言语法 | JMeter 函数语法 |
| 实时性 | 立即生效 | 可能需要下次迭代才生效 |
| 返回值 | 直接返回对象/字符串 | 返回字符串 |
| 灵活性 | 高(支持编程逻辑) | 低(简单值操作) |
JSR 223的使用
JSR 223有几种类型的组件,JSR 223预处理程序、JSR 223后置处理程序、JSR 223提取器等。
设置属性:添加JSR223 Sampler,将某个值设置为属性,可跨线程使用,设置语言为 Groovy(推荐)或 JavaScript,python也可以。
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
${__setProperty(设置一个变量,${提取的某个值},)}
设置登录判断、提取某个值、设置线程属性。设置语言为jypthon,使用JSR223 后置处理程序将提取器执行后的数据进行提取
import sys
import json
reload(sys)
sys.setdefaultencoding("utf-8")
# 获取服务器返回的数据---prev
result = prev.getResponseDataAsString() # 返回值为字符串
# 将响应体数据序列化为python对象
res_obj = json.loads(result)
# 获取服务器返回的数据。 字典[key] get(key)
token = res_obj.get("token")
status = res_obj.get("loginStatus")
# 获取用例的标题
title = vars.get("标题".decode())
## 判断正向用例登录成功
if status and title == "用户名和密码的参数和数据正常":
# 设置属性--props
props.put("TOKEN",token)
将前面的动态值替换为csv文本中需要设置的参数。使用JSR223 预处理程序,在提取器前更换csv文件的内容
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
case_data = vars.get("caseData")
is_update = vars.get("isUpdate")
if is_update == "yes":
dem_id = props.get("DEMID")
new_case_data = case_data.replace("需要更新",dem_id) #将csv中的"需要更新"替换为new_case_data变量"
vars.put("caseData",new_case_data) #将数据存到JMeter变量中
注意:props.put("TOKEN",token)和${__setProperty(DEMID,${getwid},)}这两种方式都是设置全局属性,都是将变量存储为JMeter的全局属性(Properties)供所有线程组共享。但两者在实现方式、灵活性和使用场景上有一些关键区别。当变量有多个重复的值时,通过${id_n}来选择需要的值。props.put() 在脚本中执行,可能有轻微性能开销(但Groovy优化后影响极小)。${__setProperty()} 是JMeter原生函数,解析效率更高。
由于jsr223+python的速度太慢,在做测试的时候尽量少用,最好只在设置全局属性时设置JSR223来操作。
在处理中文内容时在后面跟上.decode()。
部分实战
例如将json提取中得某一组数组+5,jsr223 后置处理器该如何操作
#使用vars局部变量
import json
# 获取原始数组 - 必须使用 getObject() 而不是 get()
original_list = vars.getObject("originalScores")
# 创建空列表存储结果
new_list = []
# 对每个元素+5并添加到新数组
for i in original_list:
new_value = i + 5
new_list.append(new_value)
# 转换为JSON字符串
new_json = json.dumps(new_list)
# 保存为JMeter变量
vars.put("newScoresParam", new_json)
# 输出调试信息
log.info("处理完成: " + new_json)
#使用props全局变量
import json
# 获取原始数组字符串
original_str = props.get("originalScores")
# 将JSON字符串解析为Python列表
original_list_plus = json.loads(original_str)
# 创建空列表存储结果
new_list = []
# 对每个元素+5并添加到新数组
for i in original_list_plus:
new_value = i + 5
new_list.append(new_value)
# 转换为JSON字符串
new_json = json.dumps(new_json)
# 保存为JMeter属性(全局)
props.put("newScoresParam", new_json)
# 输出调试信息
log.info("处理完成: " + new_json)

Comments NOTHING