jmeter中正则表达式及ForEach的使用

目录

    • 一、需求背景
    • 二、jmeter中添加正则表达式提取器
    • 三、如何输入正确的正则表达式
    • 四、正则表达式提取多个参数及应用
    • 五、ForEach的应用场景

一、需求背景

串行接口A、B、C,接口B和接口C的请求参数依赖于接口A的返回参数,在接口A的返回值中,参数是包含在value中的;
举个例子:
接口A的返回参数

{
	"url":"http://www.baidu.com/patient/todosPage?projectId=aaaaa&phaseId=12345&taskId=6789"
}

恰好接口B和接口C分别需要参数中的projectId、phaseId、taskId,那么这个时候怎么提取参数呢?

有两种方法:

  1. 在jmeter中通过BeanShell编写脚本提取value
  2. 通过正则表达式提取value

以下介绍的是如何通过正则表达式提取参数的过程。

注:正则表达式的语法可查看教程:正则表达式 - 语法

二、jmeter中添加正则表达式提取器

  1. 在「后置处理器」中选择「正则表达式提取器」,如图

  2. 提取器中每个字段代表什么?
    模块一:
    Apply to 提取数据的接口对象

    • main sample and sub-samples:对所有主请求和子请求生效
    • main sample only:只对主请求生效(默认选这个)
    • sub-samples only:只对子请求生效
    • jmeter variable name to use:对jmeter变量生效(在测试计划定义变量,在这用)

    模块二:

    • 主体:响应体(默认选这个)
    • Body(unescaped):无符号响应体,会自动忽略特殊字符,功能不稳定,一般不用
    • body as a document:响应体,会以文件形式存在(在互联网传输的接口数据都是文件),性能差
    • 信息头:响应头
    • request headers:请求头
    • url:请求的url
    • 响应代码:响应状态码
    • 响应信息:响应状态码的信息

    模块三

    • 引用名称:就是匹配成功后,保存数据的变量名
    • 正则表达式:以下是正则表达式中常用的符号
      • ():要提取的内容
      • .:匹配任意单个字符串
      • *: 匹配(*之前的符号)0次或多次
      • +:匹配(+之前的符号)1次或多次
      • ?:不要太贪婪,在找到第一个匹配项后停止
      • .*:匹配连续0个/多个字符
      • .+:匹配连续1个/多个字符
      • \ :转义,.表示匹配字符.本身
    • 模板:正则表达式中每有一个括号就相当于一个模板
      • $0$则为整个表达式匹配到的内容,就是包括小括号内跟小括号外的内容
      • $1$代表提取第一个正则表达式的数据
      • $2$则是第二个正则表达式的数据
    • 匹配数字:
      • 0代表随机选择一组
      • 1代表选择第一组
      • 2代表选择第二组
      • 为负数时代表选择全部数据,如-1
    • 缺省值:当匹配失效时,保存到引用名称的值

三、如何输入正确的正则表达式

校验正则表达式正确性可以使用网址:在线正则表达式测试

  1. 如下是需求背景中的JSON,使用网址校验正则表达式是否能提取到数据
    jmeter中正则表达式及ForEach的使用_第1张图片

  2. 如下是我填写的一个示例,解决了需求背景中提取phaseId的需求
    jmeter中正则表达式及ForEach的使用_第2张图片

  3. 在jmeter应用中,想要查看提取器具体取值参数可以添加「调试取样器」,在执行结果中就可以看到对应参数的取值

四、正则表达式提取多个参数及应用

  • 提取多个参数正则表达式如何写?
    完成步骤二后发现,使用正则表达式则只提取到phaseId一个参数,那么可以用一个正则表达式把projectId、phaseId、taskId一次性提取出来吗?
    答案是:可以,如下正则表达式

    \?projectId=(.*)&phaseId=(.*)&taskId=(.*)"
    

    需要注意的:该表达式中包含“?”,需要加一个转译字符才能被识别,否则就是一个错误的正则
    jmeter中正则表达式及ForEach的使用_第3张图片

  • 多个参数对应的「模板」和「匹配数字」如何填写?
    按照以上对模板和匹配数字的描述,模板填写$0$,匹配数字填写-1,便可以取到projectId、phaseId、taskId三个参数的值;同上引用名,所以提取出来的数据是这样的

    phaseId=获取phaseId失败
    phaseId_1=?projectId=aaaaa&phaseId=12345&taskId=6789"
    phaseId_1_g=3
    phaseId_1_g0=?projectId=aaaaa&phaseId=12345&taskId=6789"
    phaseId_1_g1=aaaaa
    phaseId_1_g2=12345
    phaseId_1_g3=6789
    

    我们在引用参数时,引用${phaseId_1_g1}就可以得到projectId,${phaseId_1_g2}就可以得到phaseId,taskId同理。

    思考:模板填写为$1$,$2$,$3$,可以取到三个参数吗?
    答案:可以取到,取到的参数值的形式为:aaaaa,12345,6789;因为模板提取中都用了“,”做分割,所以提取出来的数据也有“,”分割,如下

    phaseId=获取phaseId失败
    phaseId_1=aaaaa,12345,6789
    phaseId_1_g=3
    phaseId_1_g0=?projectId=aaaaa&phaseId=12345&taskId=6789"
    phaseId_1_g1=aaaaa
    phaseId_1_g2=12345
    phaseId_1_g3=6789
    

    对比两种模板填写方式都可以,所以选择自己觉得方便的就可以了~

  • 接口A中有多个url返回,且每个url的值都不一样,那么如何提取接口A的数据呢?
    如下返回结果:

    {
    	"url":"http://www.baidu.com/patient/todosPage?projectId=aaaaa&phaseId=12345&taskId=6789",
    	"url2":"http://www.baidu.com/patient/todosPage?projectId=bbbbb&phaseId=11111&taskId=1111",
    	"url3":"http://www.baidu.com/patient/todosPage?projectId=ccccc&phaseId=222222&taskId=2222"
    }
    

    分析:url2、url3的字段和url都是一样的,只是对应的值不一样,所以以上的正则表达式可以复用,如下是能提取到的结果
    jmeter中正则表达式及ForEach的使用_第4张图片
    则jmeter的运行结果是:

    phaseId=获取phaseId失败
    phaseId_1=aaaaa,12345,6789
    phaseId_1_g=3
    phaseId_1_g0=?projectId=aaaaa&phaseId=12345&taskId=6789"
    phaseId_1_g1=aaaaa
    phaseId_1_g2=12345
    phaseId_1_g3=6789
    phaseId_2=bbbbb,11111,1111
    phaseId_2_g=3
    phaseId_2_g0=?projectId=bbbbb&phaseId=11111&taskId=1111"
    phaseId_2_g1=bbbbb
    phaseId_2_g2=11111
    phaseId_2_g3=1111
    phaseId_3=ccccc,22222,2222
    phaseId_3_g=3
    phaseId_3_g0=?projectId=ccccc&phaseId=22222&taskId=2222"
    phaseId_3_g1=ccccc
    phaseId_3_g2=222222
    phaseId_3_g3=2222
    

    同理:${phaseId_3_g1}就能取到url3中projectId的值

五、ForEach的应用场景

串行接口A、B,接口B的执行次数依赖接口A返回值中B所需参数个数,当接口A没有返回B需要的参数时,则接口B不需要执行,举个例子:
以下是接口A的返回数据:

{
    "totalItem":2,
    "items":[
        {
            "ruleId":483
        },
        {
            "ruleId":479
        }
    ]
}

接口B中需要接口A中返回的ruleId做为请求参数,当前接口A返回id总数为"totalItem":2,那么接口B就需要针对不同的ruleId执行2次,,当接口A的"totalItem":0时,接口B则不需要执行,这样的接口用例该怎么写?
方法:将接口B加入ForEach控制器中,通过循环来实现动态请求接口次数。

  1. 在接口A中添加正则提取器,取到totalItem值(循环次数)及ruleId的值,如下是ruleId提取的正则
    jmeter中正则表达式及ForEach的使用_第5张图片
    以下是调试取样器的结果jmeter中正则表达式及ForEach的使用_第6张图片
  2. 添加「ForEach控制器」

    jmeter中正则表达式及ForEach的使用_第7张图片
    以上就可以根据接口A返回的totalItem个数动态判断接口B是否需要执行;
    当然也可以不使用ForEach也能做到循环,那就是循环控制器+计数器+BeanShell取样器拼接,这个方式比较麻烦,不推荐;以下是这个方式使用截图说明:
    jmeter中正则表达式及ForEach的使用_第8张图片jmeter中正则表达式及ForEach的使用_第9张图片
    jmeter中正则表达式及ForEach的使用_第10张图片

你可能感兴趣的:(测试工具,接口测试,正则表达式,jmeter)