jmeter 正则表达式
在进行性能测试时,我们常常需要对测试数据进行提取或匹配。这时便需要用到正则表达式。
正则表达式简介
正则表达式(Regular Expression)是一种匹配文本的模式,用于在一串文本中查找特定的字符串或字符。在JMeter性能测试中,正则表达式正是用于模糊或确定性地匹配响应数据。
正则表达式由普通字符(包括大小写字母、数字、标点符号和空格等)、元字符(特殊字符)和转义字符(用于匹配元字符的本身)等组成。下面罗列一些常见的元字符:
.
匹配任意字符(除了换行符)*
匹配前面的字符或子表达式出现0次或多次+
匹配前面的字符或子表达式出现1次或多次?
匹配前面的字符或子表达式出现0次或1次|
按照左右两侧之一匹配{}
匹配前面的字符或子表达式出现指定次数()[]
分组和范围
详细的正则表达式语法说明可以查看java.util.regex.Pattern。
jmeter正则表达式实现
jmeter正则表达式实现有多种方式:断言、提取器、响应断言、jsr223和编写对应的Java Bean等。本文只介绍其中的前三种方式。
1. 断言
断言在测试计划中有两种实现方式:Response Assertion和JSR223 Assertion
Response Assertion: 断言常用于检验请求响应中是否包含特定的字符串或特定数据格式。其中,匹配规则有两种匹配方式:模糊匹配和正则表达式匹配。
其中,左侧“模式匹配规则”选择正则表达式,表达式内容输入需要匹配的正则表达式。右侧“样本测试”中填写需要进行匹配的内容
JSR223 Assertion: JSR223 Assertion是对Response Assertion的增强版,JSR223 Assertion允许使用类似JavaScript、Groovy、Jexl等语言编写脚本,便于对数据进行特定的处理,大大增加了灵活性和可操作性。
比如,以下代码片段展示了如何利用JSR223 Assertion实现数据解析:
def pattern = /<title>(.*?)<\/title>/ // 定义正则表达式
def title = sampler.getResponseDataAsString() =~ pattern // 匹配响应数据
if (title.find()){ // 判断是否匹配到
vars.put("title",title.group(1)) // 将提取出的数据保存到JMeter变量中
}
该代码片段中,首先定义了一个正则表达式,用于匹配响应数据中的标题。接着,匹配响应数据,通过判断匹配是否成功,将提取出的数据保存到JMeter变量中。
需要注意的是,由于JSR223 Assertion是通过脚本实现的,所以对于没有编程基础的测试人员,学习成本相对较高,建议使用Response Assertion进行匹配。
2. 提取器
提取器常用于从响应数据中抽取需要的数据,以便在随后的测试环节中使用。JMeter提供了两种常用的提取器:Regular Expression Extractor和XPath Extractor。
Regular Expression Extractor
如其名,Regular Expression Extractor是一种基于正则表达式的提取器,可以将响应数据中指定的信息提取出来。
其中,左侧“应用范围”选择需要应用的目标,一般为HTTP请求中的响应数据;“正则表达式”中填写需要提取的内容所对应的正则表达式;“模板”中填写JMeter变量名,以便在后续测试中使用;“匹配规则”可选择匹配第一次出现的结果或者匹配所有出现的结果。
该提取器的实现方式为:在HTTP请求响应后,再基于设置的正则表达式提取特定数据,并将结果保存到JMeter变量中,供随后测试使用。
XPath Extractor
XPath Extractor同样是一种用于提取XML响应数据中特定信息的提取器。它支持正则表达式匹配、XPath表达式匹配和CSS选择器匹配三种方式。
其中,“XPath表达式”和“模板”与Regular Expression Extractor的配置相同。值得注意的是,当使用XPath Extractor时,需要在左侧“Namespaces”中配置命名空间,以便正确识别XML数据。
需要注意的是,由于Regular Expression Extractor和XPath Extractor的提取规则不同,所以提取方式也不同。适当选择不同的提取器有助于增加提取的准确性。例如,以下代码展示了如何使用XPath Extractor从XML数据中提取特定信息:
def xml = sampler.getResponseDataAsString() // 获取响应数据
def xmlParser = new XmlParser() // 创建xml解析器
def root = xmlParser.parseText(xml) // 解析xml数据
def testPlan = root.TestPlan // 寻找TestPlan节点
def hasThreadGroup = testPlan.childNodes().find{ it.name() == 'ThreadGroup' } // 在TestPlan节点中查找ThreadGroup节点
if (hasThreadGroup != null){ // 判断是否查找到
def numThreads = hasThreadGroup.@num_threads // 获取num_threads属性信息
log.info("num_threads: "+numThreads) // 输出提取信息
vars.put("num_threads",numThreads) // 将提取出的数据保存到JMeter变量中
}
该代码片段通过使用XmlParser解析XML数据,寻找TestPlan节点和ThreadGroup节点,并提取其中的num_threads属性信息。需要注意的是,在提取复杂的XML数据时,需要根据实际情况编写相应的解析代码。
3. 响应断言
响应断言是一种类似于Response Assertion的断言
与Response Assertion的区别在于,响应断言是在请求执行完成后再对响应内容进行断言,而Response Assertion是在请求执行前对响应内容进行断言。
响应断言可以使用正则表达式进行断言,从而选择哪种数据中提取特定信息。在进行断言时,可以选择哪些结果应该被认为是成功或失败,以及在结果为失败时应如何处理。另外,还可以定义对响应时间的额外验证。
需要注意的是,由于响应断言是在请求执行后才进行的,因此响应巨大或响应时间较长的请求可能会导致性能问题。
示例代码
下面是一些使用jmeter正则表达式的示例代码:
Response Assertion
假设我们要测试某个接口的响应数据中是否包含特定字符串“hello”,则可以设置如下Response Assertion:
在设置完成后,对于每个请求响应,JMeter都将根据正则表达式匹配响应内容。如果匹配成功,则该请求被认为是成功的。
JSR223 Assertion
假设我们要测试某个接口的响应数据中XML节点中的标题信息,我们可以使用如下代码:
def pattern = /<title>(.*?)<\/title>/ // 定义正则表达式
def title = sampler.getResponseDataAsString() =~ pattern // 匹配响应数据
if (title.find()){ // 判断是否匹配到
vars.put("title",title.group(1)) // 将提取出的数据保存到JMeter变量中
}
在配置完成后,JMeter将遍历每个响应数据,并将匹配到的信息保存到名为“title”的变量中。
Regular Expression Extractor
假设我们要测试某个接口的响应XML数据中某个节点的属性值,我们可以使用如下Regular Expression Extractor:
在配置完成后,JMeter将从每个响应XML数据中提取出book节点的属性信息,并保存到名为“bookAuthor”的变量中。
XPath Extractor
假设我们要测试某个接口的响应XML数据中某个节点的子节点名称,我们可以使用如下XPath Extractor:
在配置完成后,JMeter将提取出每个响应XML数据中指定节点的第一个子节点名称,并保存到名为“nodeName”的变量中。
结论
正则表达式作为一种灵活、通用的数据匹配和提取工具,常用于JMeter性能测试中的响应数据处理。本文主要介绍了在JMeter中使用正则表达式的三种方式:断言、提取器和响应断言,并提供了一些示例代码以供实践。当然,由于正则表达式语法复杂且易错,使用时需要认真仔细地检查正则表达式的正确性。