当前位置: 首页 > article >正文

【测试工具JMeter篇】JMeter性能测试入门级教程(六):JMeter中实现参数化的几种方式

一、参数化的定义

        什么是参数化?从字面上去理解的话,就是事先准备好数据(广义上来说,可以是具体的数据值,也可以是数据生成规则),而非在脚本中固化,脚本执行时从准备好的数据中取值。        

        参数化在自动化测试里面会经常用到,可将脚本中的某些参数使用变量来代替。这样可以避免出现这种情况:脚本中某些参数被多次引用,但是测试脚本中参数可能需要经常变动或者修改,通过参数化可以避免修改多个地方。例如登录操作时,利用GET/POST请求方式传递参数的场景,可在脚本运行时指定参数的取值范围和规则。

脚本在运行时,根据需要选取不同的参数值作为输入,该方式称为数据驱动测试(Data Driven Test),而参数的取值范围被称为数据池(Data Pool)

二、什么情况下需要用到参数化

测试数据的准备阶段我们需要用到参数化这个强大的功能。

使用场景如下:

  • 若需求每次访问某一个接口的数据不一样时,需要用到参数化,更好地模拟用户情况,常用语压力测试。
  • 需要多次获取同一数据,则可以用一个参数化来代替,在需要的地方使用这一个变量就可以了。

三、JMeter实现参数化的方式

JMeter提供了多种参数化方式,常用的几种这里总结如下:

1. 用户自定义变量(User Defined Variables):

更多用于设置全局变量,常用于数据库地址,测试环境、开发环境地址等常量配置。

2. CSV数据文件设置(CSV Data Set Config):

这种方式是通常所指的参数化。数据存储在文件中,该种参数化方式取值范围大,灵活性很强,适用于大量测试数据时使用。

3. 用户参数(User Parameter):

适用于参数取值范围很小,需要少量测试数据时使用。

4. 函数助手:

可使用函数生成随机数字和随机字符串实现参数化。

在JMeter中使用参数化变量的方式:${变量名}

四、参数化的应用详细说明

1. 用户自定义变量(User Defined Variables)

用户自定义的变量,也可以实现请求参数的参数化。

创建方式:

  • 右键快捷菜单中选择 添加-配置元件-用户自定义变量

如上图,用起来也很简单,添加变量名和相对应的值就可以了。后面引用变量和前面一样,使用${mobile}的方式。

  • 在测试计划下方也有用户定义变量

【用户定义的变量】一般并非用来做HTTP请求参数化,而是用来定义全局变量,比如参数化文件路径、host、url等。

【用户定义的变量】创建在【线程组】上,则在线程组内生效,如果创建在【Test Plan】上,则对所有线程组生效。

2. CSV数据文件设置(CSV Data Set Config):

在JMeter中提起参数化,我们默认就想到CSV Data Set Config(以下简称CSV),CSV能够读取文件中的数据并生成变量,被JMeter脚本引用,从而实现参数化。

1)CSV简介

线程组右键–>添加–>配置元件–>CSV Data Set Config,就创建了一个CSV,界面是这个样子的:

各项参数详解如下:

参 数

描 述

必 须

Name

脚本中显示的这个元件的描述性名称

Filename

文件名。待读取文件的名称。可以写入绝对路径,也可以写入相对路径(相对于bin目录),如果直接写文件名,则该文件要放在bin目录中。对于分布式测试,主机和远程机中相应目录下应该有相同的CSV文件

File Encoding

文件编码。文件读取时的编码格式,不填则使用操作系统的编码格式

Variable Names

变量名称。多个变量名之间必须用分隔符分隔。如果该项为空,则文件首行会被读取并解析为列名列表

Ignore first line

是否忽略首行?如果csv文件中没有表头,则选择false

Delimiter

分隔符。将一行数据分隔成多个变量,默认为逗号,也可以使用“\t”。如果一行数据分隔后的值比Vairable Names中定义的变量少,这些变量将保留以前的值(如果有值的话)

Allow quoted data?

是否允许变量使用双引号?允许的话,变量将可以括在双引号内,并且这些变量名可以包含分隔符

Recycle on EOF?

遇到文件结束符是否再次循环?默认为 true

Stop thread on EOF?

遇到文件结束符是否停止线程?默认为 true

Recycle on EOF?

当Recycle on EOF为False时,停止线程,当Recycle on EOF为True时,此项无意义,默认为 false

Sharing mode

线程共享模式。1、All threads(默认):一个线程组内,各个线程(用户)唯一顺序取值;2、current thread:一个线程组内,各个线程(用户)各自顺序取值;3、线程组各自独立,但每个线程组内各个线程(用户)唯一顺序取值;

需要着重说明一下的是Sharing mode,也就是线程共享模式。线程共享模式,是指多个线程对文件数据取值顺序模式,JMeter提供了3种模式:

  • All threads:所有线程。如果脚本有多个线程组,在这种模式下,各线程组的所有线程也要依次唯一顺序取值。例如,脚本有2个线程组,各有2个线程,文件内有5行数据,脚本运行时,将如下图一样循环往复取值:

  • Current thread group:当前线程组。各个线程组之间隔离,线程组内的线程顺序唯一取值。

  • Current thread:当前线程。这种模式下,每个线程独立,顺序唯一取值。

2)CSV实例

下面看一个实例。首先有userInfo.txt的文件,放置在bin目录中,内容如下:

  • 文件名:文件在bin目录中,使用相对目录
  • 变量名称:两列数据分别属于mobile和password两个变量
  • 分隔符:以逗号分割

在HTTP请求中引用CSV生成的变量的方式是${变量名}的方式:

运行脚本,察看结果树:

可以看到,文件中的数据被脚本成功引用。JMeter使用CSV实现参数化就是这么简单。

3)注意事项

CSV使用中最常见的一个问题是文件路径不对。当遇到这种问题时,因为运行脚本没有明显提示,许多人遇到后会感觉很懵,不知道问题在哪。其实,仔细观察会发现右上角黄色三角处数字在增加,点击该区域便打开了日志,日志里记录了相应错误:File userInfo2.txt must exist and be readable,也就是提示参数化文件不存在或路径不可达。

3. 用户参数(User Parameter)

User Parameters,也就是用户参数,也能实现参数化。

创建方式:HTTP请求上右键–>添加–>前置处理器(Pre processors)–>用户参数。

通过【添加变量】添加mobile和password两个变量,通过【添加用户】添加3组数据:

在HTTP请求中引用参数化的数据:

运行脚本,设置好的数据被成功引用。

这种方式相对来说简易一些,数据范围有限,适用场景也少。而且,每个线程会一直使用一组数据。例如,设置4个线程并发,那么线程1使用用户_1的数据,线程2使用用户_2的数据,线程3使用用户_3的数据,线程4使用用户_1的数据,无论各个线程循环多少次。

4. 函数助手

  • 函数助手的打开方式

在JMeter中打开函数助手界面的方式有如下两种:

第一种:“工具”菜单-->函数助手对话框或者后面显示的快捷键Ctrl+Shift-F1

第二种:在工具栏中常用功能的快捷按钮,如下图:

  • 函数助手界面详细介绍
  • 具体函数详细介绍

JMeter函数是一种特殊值,可用于除测试计划外的任何组件。

函数调用的格式如下所示:

${__functionName(var1,var2,var3)}

其中,“__”是两个英文半角的下划线,functionName为函数名,括号内是函数的参数,无参数时可以不用括号,如${__UUID},其中参数视不同函数而定。

Tips:

如果参数包含逗号,那么一定要使用“\”来转义,否则JMeter会把它当作一个参数分隔符

实际使用时,可通过函数助手对话框选择函数,设置参数后,点击生成按钮生成函数字符串。

我们介绍了前四种函数类型,这一篇我们将最后两种函数类型介绍和分享一下。

函数类型

函数名称

函数作用

启用版本

脚本函数

__BeanShell

执行 beanshell 脚本

1.X

__javaScript

执行 js 脚本

1.9

字符串操作函数

__split

根据分隔符拆分字符串为多个变量

2.0.2

__changeCase

转换大小写

4.0

__regexFunction

使用正则表达式解析之前的响应结果

1.X

属性信息函数

__isPropDefined

判断属性是否存在

4.0

__property

对多个整数求和

1.8.1

__P

简化的属性函数,用于与命令行上定义的属性一起使用

2.0

__setProperty

简化的属性函数,用于与命令行上定义的属性一起使用

2.0

数据输入函数

__StringFromFile

从文本文件中读取字符串,每次调用读取一行

1.9

__FileToString

把文件读取成一个字符串,每次调用都是读取整个文件

2.4

__CSVRead

返回当前正在执行的线程的编号

1.9

__XPath

使用 XPath 语法匹配 XML文件

2.0

数据计算函数

__counter

计数器函数

1.9

__intSum

对多个整数求和

1.8.1

__longSum

长整型求和

2.3.2

__Random

返回指定最大值和最小值之间的随机整数

1.9

__RandomDate

返回给定开始日期和结束日期值之间的随机日期

3.3

_RandomString

根据给定的字符生成指定长度的随机字符串

2.6

__UUID

通用唯一标识符函数

2.9

获取信息函数

__TestPlanName

返回当前测试计划的名称

__threadGroupName

返回当前线程组的名称

4.1

__threadNum

返回当前正在执行的线程的编号

1.X

__samplerName

返回当前请求的名称

2.5

__log

输出日志信息

2.2

__time

以多种格式返回当前时间

2.2

4.1 脚本函数

 4.1.1__BeanShell函数

JMeter支持BeanShell脚本语言,JMeter函数助手中提供BeanShell函数支持,__BeanShell函数入参可以是BeanShell语法的程序语句或者BeanShell脚本文件。调出函数面板,我们在“值”中输入的是两个字符串相加,然后点击“生成”按钮,就会生成一串以$开头的表达式,表达式在请求(Sampler)中可以直接调用。

1)我们先来看看这个__BeanShell 长得是啥样子,路径:函数助手 > 选择__BeanShell ,如下图所示:

2)关键参数说明:

它有两个参数,第一个参数是要执行的语句,可以是beanshell语句或者是文件地址,是必选参数;第二个参数是保存结果的变量名称,非必选参数。

3)实例

  • ${__BeanShell(123456*789)}:返回97406784,如下图所示:

  • ${__BeanShell(source("function.bsh"))}:会执行外部脚本function.bsh,并返回结果,如下图所示:

文件里代码:System.out.print("bjhg");

返回结果:

  • ${__BeanShell(import java.util.*;Properties props = System.getProperties();String osName = props.getProperty("os.name");if(osName.contains("Windows"))return 443;return 8443;)}:判断Windows返回端口443
import java.util.*;
Properties props = System.getProperties();
String osName  = props.getProperty("os.name");
if(osName.contains("Windows"))
    return 443;
return 8443;

  • 与beanshell元件比较:

该函数与beanshell元件(beanshell sampler、beanshell preprocess等)作用是一样的,只是beanshell函数更常用于一些简单的判断或计算等,可以把少量的脚本放在函数中直接赋值给一个变量,而不用总是添加beanshell元件。

 4.1.2__javaScript

用来执行 JavaScript 脚本片段,并返回结果值。

该函数会调用标准的 JavaScript 解释器,还可以直接调用 jmeter 的内置函数。

注意:文本字符串要添加必要的引号。如果表达式中有逗号,要确保对其转义。

例如:Missing open brace for subscript{sp}'.slice(7\,99999))},对 7 之后的逗号进行了转义。

1)我们先来看看这个__javaScript长得是啥样子,路径:函数助手 > 选择__javaScript,如下图所示:

2)关键参数说明:

第一个参数:JavaScript代码片段,待执行的JavaScript代码片段。例如:

  • new Date():返回当前日期和时间
  • Math.floor(Math.random()*(${maxRandom},+1)):在0 和变量maxRandom之间的随机数
  • minRandom+Math.floor(Math.random()∗({maxRandom}-minRandom+1)):在变量minRandom和maxRandom之间的随机数"

第二个参数:变量名,重用函数计算值的引用名

请记得为文本字符串添加必要的引号。另外,如果表达式中有逗号,请确保对其转义。例如,Missing open brace for subscript{sp}'.slice(7\,99999))},对7之后的逗号进行了转义。

3)实例

4.2 字符串操作函数

4.2.1__split

根据分隔符拆分字符串为多个变量。

当两个分隔符中间没有字符时,返回 ?

被拆分出来的字符串,保存在变量中,类似这样:VAR1,{VAR_2} ...,总个数是

如果最后一个字符是分隔符,也会返回 ?

函数__split会通过分隔符来拆分传递给它的字符串,并返回原始的字符串。如果分隔符紧挨在一起,那么函数就会以变量值的形式返回"?"。

拆分出来的字符串,以变量${VAR_1}、{VAR_2}…以此类推的形式加以返回。JMeter 2.1.2及其以后版本,拖尾的分隔符会被认为缺少一个变量,会返回"?"。

另外,为了更好地配合ForEach控制器,现在__split会删除第一个不用的变量(由前一次分隔符所设置)。

1)我们先来看看这个__split长得是啥样子,路径:函数助手 > 选择__split,如下图所示:

2)关键参数说明:

待拆分字符串

一个待拆分字符串,例如“a|b|c”

变量名

重用函数计算值的引用名

分隔符

分隔符,例如“|”。如果省略了此参数,函数会使用逗号做分隔符。需要注意的是,假如 要多此一举,明确指定使用逗号,需要对逗号转义,如“\,”

3、示例:

定义字符串:
VAR="a||c|"

调用 split 函数:
${__split(${VAR},VAR,|)}
返回 "a||c|",并生成如下变量:
VAR_n=4 
VAR_1=a 
VAR_2=? 
VAR_3=c 
VAR_4=? 
VAR_5=null

4.2.2__changeCase

根据指定的模式,修改字符串大小写;

可选模式有:UPPERLOWERCAPITALIZE

1)我们先来看看这个__changeCase长得是啥样子,路径:函数助手 > 选择__changeCase,如下图所示:

2、关键参数说明:

第一个参数:需要修改的字符串

第二个参数:对字符串作用的模式3种

第三个参数:字符串修改后,存储的变量名,赋值的变量名

3、示例:

(1)UPPER--转换成大写字母: ${__changeCase(Avaro omnia desunt\, inopi pauca\, sapienti nihil,UPPER,)} 返回 AVARO OMNIA DESUNT, INOPI PAUCA, SAPIENTI NIHIL

(2)LOWER--转换成小写字母: ${__changeCase(LABOR OMNIA VINCIT IMPROBUS,LOWER,)} 返回 labor omnia vincit improbus

(3)CAPITALIZE--单词首字母大写: ${__changeCase(omnibus viis romam pervenitur,CAPITALIZE,)} 返回 Omnibus viis romam pervenitur

4.2.3__regexFunction

使用正则表达式解析之前的响应结果。

1)我们先来看看这个__regexFunction长得是啥样子,路径:函数助手 > 选择__regexFunction,如下图所示:

该函数使用用户提供的正则表达式来解析前面的服务器响应(或者是某个变量值)。函数会返回一个有模板的字符串,其中携带有可变的值。

在函数的第6个参数中,可以指定一个引用名,保存变量值,供后续调用。__regexFunction还可以被用来保存值,以便供后续使用。在函数的第6个参数中,测试人员可以指定一个引用名。在函数执行以后,测试人员可以使用用户定义值的语法来获取同样的值。例如,如果测试人员输入"refName"作为第6个参数,那么测试人员可以使用

变量调用示例:

Name of variable in which to store the result:在这个参数中设置变量名为 refName ,那么我们可以使用:

${refName}来引用第2个参数(Template for the replacement string)的计算结果,这依赖于函数的解析结果。

${refName_g0}来引用函数解析后发现的所有匹配结果。

${refName_g1}来引用函数解析后发现的第一个匹配组合。

${refName_g#}来引用函数解析后发现的第n个匹配组合。

${refName_matchNr}来引用函数总共发现的匹配组合数目。

2)具体参数描述如下:

函数参数

描述

是否必需

第1个参数

第1个参数是用于解析服务器响应数据的正则表达式,它会找到所有匹配项;如果希望将表达式中的 某部分应用在模板字符串中,一定记得为其加上圆括号。例如,<a href="(.*)">,这样就会将链 接的值存放到第一个匹配组合中(这里只有一个匹配组合)。又如,<input type="hidden" name="(.*)"value="(.*)">,在这个例子中,链接的name作为第一个匹配组合,链接的value会 作为第二个匹配组合,这些组合可以用在测试人员的模板字符串中。

第2个参数

这是一个模板字符串,函数会动态填写字符串的部分内容。要在字符串中引用正则表达式捕获的匹配组 合,请使用语法:[groupnumber][groupnumber]。例如11或者 22,模板可以是任何字符串。

第3个参数

第3个参数告诉JMeter使用第几次匹配;测试人员的正则表达式可能会找到多个匹配项,对此, 有4种选择: n 整数,直接告诉JMeter使用第几个匹配项; n “1”对应第一个匹配,“2”对应第二个匹配,以此类推; n RAND,告诉JMeter随机选择一个匹配项; n ALL,告诉JMeter使用所有匹配项,为每个匹配项创建一个模板字符串,并将它们连接在一起 n 浮点值0到1之间,根据公式(找到的总匹配数目*指定浮点值)计算使用第几个匹配项,计算值 向最近的整数取整

否,默认值为1

第4个参数

如果在上一个参数中选择了“ALL”,那么这第4个参数会被插入到重复的模板值之间

第5个参数

如果没有找到匹配项返回的默认值

第6个参数

重用函数解析值的引用名,参见上面内容

第7个参数

输入变量名称。如果指定了这一参数,那么该变量的值就会作为函数的输入,而不再使用前面的采样结 果作为搜索对象

[groupnumber]

[groupnumber]。例如

1

1或者

2

2,模板可以是任何字符串。 是 第3个参数 第3个参数告诉JMeter使用第几次匹配;测试人员的正则表达式可能会找到多个匹配项,对此, 有4种选择: n 整数,直接告诉JMeter使用第几个匹配项; n “1”对应第一个匹配,“2”对应第二个匹配,以此类推; n RAND,告诉JMeter随机选择一个匹配项; n ALL,告诉JMeter使用所有匹配项,为每个匹配项创建一个模板字符串,并将它们连接在一起 n 浮点值0到1之间,根据公式(找到的总匹配数目*指定浮点值)计算使用第几个匹配项,计算值 向最近的整数取整 否,默认值为1 第4个参数 如果在上一个参数中选择了“ALL”,那么这第4个参数会被插入到重复的模板值之间 否 第5个参数 如果没有找到匹配项返回的默认值 否 第6个参数 重用函数解析值的引用名,参见上面内容 否 第7个参数 输入变量名称。如果指定了这一参数,那么该变量的值就会作为函数的输入,而不再使用前面的采样结 果作为搜索对象 否

其实这个函数的作用跟正则表达式提取器的作用是类似的。

4.3 属性信息函数

4.3.1 __isPropDefined

用于判断属性是否存在。

1)我们先来看看这个__isPropDefined长得是啥样子,路径:函数助手 > 选择__isPropDefined,如下图所示:

2)关键参数说明:

Name of property:属性名称

3、示例:

${__isPropDefined(START.HMS)}
判断属性 START.HMS 是否存在,返回 true。

4.3.2 __property

获取属性值。获取Jmeter的属性,%JMETER_HOME%\bin\jmeter.properties

1)我们先来看看这个__property长得是啥样子,路径:函数助手 > 选择__property,如下图所示:

2)关键参数说明:

Name of property:属性名称;

Name of variable in which to store the result (optional):变量名;

default Value:默认值

3)示例:

${__property(user.dir)}  返回 user.dir 的值。
${__property(user.dir,UDIR)}   返回 user.dir 的值,并保存在变量 UDIR 中。

${__property(abcd,ABCD,atod)}   返回属性 abcd 的值,如果该属性未定义则返回 atod,并保存在变量 ABCD 中。
${__property(abcd,,atod)}    返回属性 abcd 的值,如果该属性未定义则返回 atod,不保存结果值。
${__property(log_level.jmeter,log_Level,)}

4.3.3 __P

这是一个简化的属性函数,用于与命令行上定义的属性一起使用。获取命令行中定义的属性,非GUI方式运行测试计划时这个函数可用来做参数化,由运行命令动态指定参数值,方便与Jenkins等集成完成性能测试工作

_property 函数不同,没有选项可以将值保存在变量中,如果不提供默认值,则假定为1。

1、我们先来看看这个__P长得是啥样子,路径:函数助手 > 选择__P,如下图所示:

2、关键参数说明:

Name of property:属性名称;

default Value:默认值

3、示例:

代码语言:javascript

复制

在脚本中定义如下两个函数:
${__P(group1.threads, 10)}
${__P(group1.loops)}

在命令行中调用:
jmeter -Jgroup1.threads=50  -Jgroup1.loops=100   执行时,两个参数分别是 50、100。

若命令行中不设置属性,执行时,两个参数分别是 10、1。

4.3.4 __setProperty

该函数用于设置 JMeter 属性的值。

函数的默认返回值是空字符串,因此该函数可以被用在任何地方,只要对函数本身调用是正确的。

1)我们先来看看这个__setProperty长得是啥样子,路径:函数助手 > 选择__setProperty,如下图所示:

通过将函数可选的第3个参数设置为"true",函数就会返回属性的原始值。

属性对于JMeter是全局的,因此可以被用来在线程和线程组之间通信。

2)关键参数说明:

Name of property:属性名称;

Value of property:属性值;

Return Original Value of property (default false)?:是否返回函数结果

3)实例

${__setProperty(log_level.jmeter,Debug,true)}

4.4 数据输入函数

4.4.1 __StringFromFile

从文件中读取内容,一行一行的读取,读完再从头开始。

1)我们先来看看这个__StringFromFile长得是啥样子,路径:函数助手 > 选择__StringFromFile,如下图所示:

作用:用于从文本文件中读取字符串,每次读取一行,支持读取多个文件。

使用配置元件CSV Data Set Config ,也能达到相同的目的,而且方法更简单,但是它目前不支持多个输入文件。

每次调用函数,都会从文件中读取下一行。当到达文件末尾时,函数又会从文件开始处重新读取,直到最大循环次数。如果在一个测试脚本中对该函数有多次引用,那么每一次引用都会独立打开文件,即使文件名是相同的(如果函数读取的值,在脚本其他地方也有使用,那么就需要为每一次函数调用指定不同的变量名)。

如果在打开或者读取文件时发生错误,那么函数就会返回字符串 **ERR**

2)参数

参数

描述

是否必填

文件名

文件名的路径 (路径可以相对于 JMeter 启动目录)。如果使用序列号,路径名称应该适合传递到 DecimalFormat。

变量名

用于后续调用该函数的变量名称

启动序号

初始序列号(如果省略,则将结束序列号视为循环计数)

末端序号

最终序列号(如果省略,序列号可以无限制地增加)

启动序号:初始的序列号,如果省略,那么结束序列号就代表文件的循环读取次数。

末端序号:结束序列号,如果省略,那么序列号会无限增长。

3)示例

读取单个文件:
${_StringFromFile(test.txt,,,)}    读取test.txt

读取多个文件,需要在文件名中使用序列号:
${_StringFromFile(PIN.DAT,,,2)}    读取 PIN.DAT 两次
${_StringFromFile(PIN#'.'DAT,,1,3)}    读取 PIN1.DAT PIN2.DAT PIN3.DAT
${_StringFromFile(pin000'.'dat,,6,8)}    读取 pin006.dat pin007.dat pin008.dat

使用序列号时,路径名被用作 java.text.DecimalFormat 的格式字符串。当前序列号作为唯一参数传入。如果未指定开始序列号,则按原样使用路径名称。

4、格式化序列

常用的两个格式化序列:

  • #:插入数字,没有前导零或空格。
  • 000:插入数字,数字不足三位时,将插入前导零补足三位;数字超过三位时,则插入数字实际位数。

用法说明:

代码语言:javascript

复制

在不带前导零的情况下插入数字:
pin#'.'dat -> pin1.dat, ... pin9.dat, pin10.dat, ... pin9999.dat

带前导零的情况下插入数字:
pin000'.'dat -> pin001.dat ... pin099.dat ... pin999.dat ... pin9999.dat

在不带前导零的情况下追加数字:
pin'.'dat# -> pin.dat1, ... pin.dat9 ... pin.dat999

注意:上面的 . 是格式化字符,必须用单引号括起来。

4.4.2__FileToString

把文件读取成一个字符串,每次调用都是读取整个文件。读取文件保存至变量中。

如果出现打开或读取文件的错误,则函数将返回字符串 **ERR**

1、我们先来看看这个__FileToString长得是啥样子,路径:函数助手 > 选择__FileToString,如下图所示:

2、关键参数说明:

参数

描述

是否必填

文件名

文件名的路径。(路径可以相对于JMeter启动目录)

文件编码

用于读取文件的编码。如果未指定,则使用平台默认值。

变量名

用于后续调用该函数的变量名称。

3、实例

代码语言:javascript

复制

${__FileToString(C:\Users\DELL\Desktop\user_info.csv,utf-8,user_info)}

读取结果可能会出现中文乱码,注意把文件修改成UTF-8的编码格式保存。

4.4.3 __CSVRead

从文件读取指定列的值(读取固定值/读取动态值/使用文件别名)

1)我们先来看看这个__CSVRead长得是啥样子,路径:函数助手 > 选择__CSVRead,如下图所示:

作用如下:

  • 从一个 CSV 文件中返回一个字符串,支持多个文件名。
  • 当第一次调用该函数时,文件将被打开并读取到一个内部数组中。如果检测到空行,这将被视为文件的末尾。
  • 所有对同一文件名的后续引用都使用相同的内部数组,文件名区分大小写。
  • 每个线程都有自己的指向文件数组中当前行的内部指针。当线程首先引用文件时,它将在数组中分配下一个空闲行,因此每个线程将访问与所有其他线程不同的行(除非数组中的线程多于行)。

2)参数

参数

描述

是否必填

文件名

要读取的文件名

列号

文件中的列号。0–第一列,1–第二列,next–文件的下一行。

3)示例

读取文件中的第1行第1列:
${__CSVRead(random.txt,0)}

读取文件中的第1行第2列,并进入文件下一行:
${__CSVRead(random.txt,1)}${__CSVRead(random.txt,next)}

读取文件第2行第1列:
${__CSVRead(random.txt,0)}

读取文件中的第2行第2列,并进入文件下一行:
${__CSVRead(random.txt,1)}${__CSVRead(random.txt,next)}

读取文件可能会出现中文乱码,修改文件的编码为:ANSI编码格式就可以了。

注意:

  • 该函数不适合用于大型文件,因为整个文件都存储在内存中。
  • 对于较大的文件,最好使用 CSV Data Set Config 或者 StringFromFile
  • 默认情况下,该函数在每个逗号处拆分行。如果要输入包含逗号的列,则需要通过设置属性将分隔符更改为不出现在任何列数据中的字符,修改 jmeter.properties 文件中的 csvread.delimiter=
4.4.4 __XPath

根据xpath获取xml节点内容,没有匹配到,则返回空字符串。

1、我们先来看看这个__Xpath长得是啥样子,路径:函数助手 > 选择__Xpath,如下图所示:

2、关键参数说明:

XML file to get values from:待解析的xml文件;

XPath expression to match against :xpath表达式匹配xml节点

注意:

  • 该函数读取 XML 文件,并在文件中寻找与指定 XPath 相匹配的地方。
  • 每调用函数一次,就会返回下一个匹配项。到达文件末尾后,会从头开始。如果没有匹配的节点,那么函数会返回空字符串,另外,还会向JMeter日志文件写一条警告信息。
  • 整个节点列表都会被保存在内存之中,所以文件较大时不适合使用。

3、示例:

代码语言:javascript

复制

宏哥找了一个JMeter安装目录下的一个build.xml文件,进行实战,如下:默认取值1,name=all,修改[2],name=run。

代码语言:javascript

复制

${__XPath(D:\software\apache-jmeter-5.1.1\extras\build.xml,//target[2]/@name)}

这会找到 build.xml 文件中的所有目标节点,并返回下一个 name 属性的内容。

4.5 数据计算函数

4.5.1 __counter

作为一个计数器使用,支持多线程(多用户)。功能:这个函数是一个计数器,用于统计函数的使用次数,它从1开始,每调用这个函数一次它就会自动加1,它有两个参数,第一个参数是布尔型的, 只能设置成“TRUE”或者“FALSE”,如果是TRUE,那么每个用户有自己的计数器,可以用于统计每个线程歌执行了多少次。如果是FALSE,那就 使用全局计数器,可以统计出这次测试共运行了多少次。第二个参数是“函数名称”。

1)我们先来看看这个__counter长得是啥样子,路径:函数助手 > 选择__counter ,如下图所示:

2)关键参数说明

TRUE, for each user to have own counter, FALSE for a global counter:计数变量i,

Name of variable in which to store the result (optional):是否为线程计数器True/False

3)实例

${__counter(FALSE,i)}; 全局计数器
${__counter(TRUE,i)}; 每个用户有自己的计数器

注意:

  • 每次调用该计数器函数都会产生一个新值,从1开始每次加1。
  • 计数器既可以被配置成针对每个虚拟用户是独立的,也可以被配置成所有虚拟用户公用的。
  • 如果每个虚拟用户的计数器是独立增长的,那么通常被用于记录测试计划运行了多少遍。全局计数器通常被用于记录发送了多少次请求。
  • 计数器使用一个整数值来记录,允许的最大值为 2,147,483,647。
  • 目前计数器函数实例是独立实现的(JMeter 2.1.1及其以前版本,使用一个固定的线程变量来跟踪每个用户的计数器,因此多个计数器函数会操作同一个值)。全局计数器(FALSE)的每个计数器实例都是独立维护的。
  • 该函数也有对应的配置元件:计数器,功能类似。
4.5.2 __intSum

  整数求和,多个数字之间用逗号分隔。用于计算多个整数的和,可以是计算正整数和负整数的和,它有N个参数,最少有3个参数,最多不限。最后一个参数是函数名称,前面的其它参 数是要求和的整数。这个函数在函数对话框中只显示3个参数,如果要计算多个整数,可以通过添加参数实现,不过最后一个参数一定要是函数名称。再添加的参数 会在函数名称后面,这个时候,需要我们手动将函数名称参数放到最后一个。

1)我们先来看看这个__intSum长得是啥样子,路径:函数助手 > 选择__intSum ,如下图所示:

函数 __intSum 可以被用来计算两个或者更多整数值的和。至少需要两个整数,如果指定变量名则名称中必须包含一个非数字字母,否则它会被当成另一个整数值,而被函数用于计算。

注意: 在 4.0 版本之前,当有多个整数时,要通过点击添加按钮来增加参数,但是需要注意的是,添加完参数后,点击 生成 的函数默认是把手动添加的函数放在后面,这时需要手动调整变量名的位置,把它放到最后,否则会报错。 在 4.0 版本之后,该问题已解决。

4.0 之前版本添加多个整数示例如下:

4.5.3 __longSum

该函数用来计算两个或更多长整型值的和,使用方法跟上面的 __intSum 函数一样,这里不再赘述。

1、我们先来看看这个__longSum长得是啥样子,路径:函数助手 > 选择__longSum ,如下图所示:

2、关键参数说明

函数参数

描述

是否必需

第1个参数

第1个长整型值

第2个参数

第2个长整型值

第n个参数

第n个长整型值

最后一个参数

重用函数计算值的引用名。如果用户指 定了这一参数,那么引用名中必须包含一个 非数字字母,否则它会被当成另一个长整 型值,而被函数用于计算

3、实例

${__longSum(1,2,sum)}

4.5.4 __Random

随机数函数返回指定最大值和最小值之间的随机整数。_Random函数是从某数据段随机读取数据替换参数,当需要添加多条数据记录且某些字段需要唯一性时使用,使用该函数随机生成的数据是数字。

Tips:一般在新增的时候,固定字符串后加个随机数,避免重复。当我们设置的线程数超过随机数范围时,随机数将会重复生成

1、我们先来看看这个__Random长得是啥样子,路径:函数助手 > 选择__Random ,如下图所示:

2、关键参数说明

一个范围内的最小值:即我们所要取的随机数的最小值,上述设置为1,生成的随机数将不会小于1

一个范围内允许的最大值:即我们所要取的随机数的最大值,上述设置为100,生成的随机数将不能超过100

Name of variable in which to store the result(optional)为函数名称名称:这里我们设置为random,即用于存储在测试计划中其他的方式使用的值

3、实例

代码语言:javascript

复制

返回 0--10 之间的随机整数:

代码语言:javascript

复制

${__Random(1,10,var)}

4.5.5 __RandomDate

返回位于给定开始日期和结束日期值之间的随机日期。

1、我们先来看看这个__Randomdate长得是啥样子,路径:函数助手 > 选择__Randomdate,如下图所示:

2、关键参数说明

Format string for DateTimeFormatter (optional) (default yyyy-MM-dd):日期格式化方法,默认为yyyy-MM-dd;

Start date (optional) (default: now):为开始日期,格式必须和日期格式化方法一致,如格式化方法不填,则此处格式需为2018-02-03,如不填则默认为现在;

End date:和Start date类似,但是此项必填;

String format of a locale (ex: fr_FR , en_EN) (optional):日期相关的地区信息,可以不填;

Name of variable in which to store the result (optional):参数名称,也可以不填;

3、实例

示例:

${__RandomDate(,,2050-07-08,,)} 随机返回一个从现在到 2050-07-08 的日期,例如 2039-06-21

${__RandomDate(dd MM yyyy,,08 07 2050,,)} 返回带有自定义格式的随机日期,如 04 03 2034

4.5.6 _RandomString

根据给定的字符,生成指定长度的随机字符串。

1、我们先来看看这个__RandomString长得是啥样子,路径:函数助手 > 选择__RandomString ,如下图所示:

2、关键参数说明

Random string length生成的随机字符的长度

Chars to use for random string generation用来生成随机字符串的字符,可以是纯数字,纯字符,字符字母数字组合。

Name of variable in which to store the result (optional)保存结果的变量

3、实例

例如:${__RandomString(6,abcdefgh1234566,ranstr)}

随机生成一个6位长度的字符串,并保存在变量 ranstr 中,后续可以通过 ${ranstr} 来调用。

4.5.7 __UUID

通用唯一标识符函数,生成一个32位不重复的随机字符串。

1、我们先来看看这个__UUID长得是啥样子,路径:函数助手 > 选择__UUID ,如下图所示:

2、示例:

${__UUID()} 返回结果类似:c69e0dd1-ac6b-4f2b-8d59-5d4e8743eecd

4.6 获取信息函数

4.6.1 __TestPlanName

用法:${__TestPlanName},返回当前测试计划的名称;

如:测试计划名称是 Demo.jmx, 即返回 Demo.jmx。注意:Save Test plan before calling __TestPlanName function(调用此函数时,必须先保存一个测试计划)

1、我们先来看看这个__TestPlanName长得是啥样子,路径:函数助手 > 选择__TestPlanName ,如下图所示:

2、实例

4.6.2 __threadGroupName

用法:${__threadGroupName},返回当前线程组的名称,从 4.1 版本开始启用。

该函数不能用在任何配置元件中(如用户定义的变量),因为配置元件是由另外的独立线程运行的,它也不能在测试计划(Test Plan)中使用。

1、我们先来看看这个__threadGroupName长得是啥样子,路径:函数助手 > 选择__threadGroupName,如下图所示:

4.6.3 __threadNum

用法:${__threadNum},返回当前正在执行的线程的编号,而且不依赖于线程组;

也就是说以这个函数的结果来看,不能区别线程组1的线程#1 和 线程组2的线程#1,如下图所示:

不能用在配置元件 和 测试计划中。

1、我们先来看看这个__threadNum长得是啥样子,路径:函数助手 > 选择__threadNum,如下图所示:

4.6.4 __samplerName

用法:${__samplerName()},返回当前请求的名称。获取当前按sampler的名称。

1、我们先来看看这个__samplerName长得是啥样子,路径:函数助手 > 选择__samplerName ,如下图所示:

4.6.5 __log

记录一条日志,并返回函数的输入字符串。

1、我们先来看看这个__log长得是啥样子,路径:函数助手 > 选择__log ,如下图所示:

可以设置不同的日志级别,如 OUTERR 将会分别输出记录到 System.outSystem.err 中。在这种情况下,输出总是会被打印(它不依赖于当前的日志设置)。

示例:

代码语言:javascript

复制

${__log(Message)}:写入日志文件,形如 "...thread Name : Message"。

${__log(Message,OUT)}:写到控制台窗口。

${__log(${VAR},,,VAR=)}:写入日志文件,形如"...thread Name VAR=value"。
4.6.6 __time

以多种格式返回当前时间;返回当前时间,可指定返回格式,由SimpleDateFormat类处理函数格式

  • 年:yyyy
  • 月:MM
  • 日:dd
  • 时:hh
  • 分:mm
  • 秒:ss

如果省略了格式字符串,那么函数会以毫秒的形式返回当前时间。其他情况下,当前时间会被转成简单日期格式。

jmeter 中默认定义的时间格式属性值有:

代码语言:javascript

复制

YMD = yyyyMMdd。
HMS = HHmmss。
YMDHMS = yyyyMMdd-HHmmss。
USER1 = JMeter属性time.USER1。
USER2 = JMeter属性time.USER2。
用户可以通过修改JMeter属性来改变默认格式,例如,time.YMD=yyMMdd。

1、我们先来看看这个__time长得是啥样子,路径:函数助手 > 选择__time ,如下图所示:

2、关键参数说明

Format string for DateTimeFormatter (optional) (default yyyy-MM-dd):日期格式化方法,默认为yyyy-MM-dd;

Name of variable in which to store the result (optional):参数名称,也可以不填;

3、实例

使用示例:

${__time()} 返回'1548133155699'

${__time(YMD,)} 返回'20190122'

${__time(dd/MM/yyyy,)} 返回'22/01/2019'


http://www.kler.cn/a/422062.html

相关文章:

  • WordPress ElementorPageBuilder插件 任意文件读取漏洞复现(CVE-2024-9935)
  • 重生之我在异世界学编程之C语言:选择结构与循环结构篇
  • 2024前端框架年度总结报告(二):新生qwik+solid和次新生svelte+Astro对比 -各自盯着前端的哪些个痛点 - 前端的区域发展差异
  • UE5 C++ 不规则按钮识别,复选框不规则识别 UPIrregularWidgets
  • Redis设计与实现读书笔记
  • 【STM32 Modbus编程】-作为主设备读取线圈和输入
  • 利用Python爬虫获取淘宝关键词接口的深入解析
  • LeetCode78:子集
  • unity与android拓展
  • 量化交易系统开发-实时行情自动化交易-8.8.同花顺 SuperMind 平台
  • 【Oracle11g SQL详解】子查询的分类与嵌套查询实例
  • Typora设置自动上传图片到图床
  • Linux查看系统基本信息
  • 推荐文章:FLUI Framework——打造流畅的微软界面体验
  • Mysql外键约束与关联表操作
  • 讯方智汇云校HarmonyOS培训,培养鸿蒙原生应用开发人才
  • TypeScript (一)运行环境配置,数据类型,可选类型,联合类型,type与interface,交叉类型,断言as,字面量类型,类型缩小
  • 【青牛科技】超低功耗混合信号处理器由多种设备组成的流量计电路芯片——D8331
  • Linux之信号集基础
  • 怎么自己创建一个网站? 开发语言首选 java,使用CMS网站内容管理系统是不错的选择
  • Redis设计与实现第17章 -- 集群 总结2(执行命令 重新分片)
  • 能源投资工程VS智能驾驶,DolphinScheduler如何当好传统行业与前沿科技的桥梁?
  • [网络] UDP通信接口及一些简易项目
  • vue 通过 mqtt 实现实时接收消息
  • 算法笔记:力扣24. 两两交换链表中的节点
  • centos7下安装promethus及grafana