• 0
  • 0
分享
  • JMeter内置变量大揭秘:含义,用法和实例——软件测试圈
  • 小丸子🍡 2024-09-29 13:36:40 字数 5131 阅读 661 收藏 0

  在JMeter中,有一些内置的变量,可以帮助我们在测试过程中存储和使用一些数据。这些内置变量有四种:vars,props,prev和sample。

  vars变量

  vars变量是JMeterVariables类的一个实例,它是一个Map类型的对象,可以存储String或Object类型的数据。vars变量的作用域是当前线程组,也就是说,只有同一个线程组内的线程才能访问和修改同一个vars变量。如果不同的线程组需要共享数据,就不能使用vars变量。

  vars变量的使用方法很简单,我们可以在BeanShell Sampler或JSR223 Sampler中使用以下语法来获取和设置vars变量:

  // JSR233  groovy 脚本
  //获取vars变量
  String value = vars.get("key");
  Object obj = vars.getObject("key");
  //设置vars变量
  vars.put("key", "value");
  vars.putObject("key", new Object());

1-1.png

  直接使用${key}来引用vars变量的值。

  vars变量的一个常见用途是保存上一个请求的响应数据,以便后续请求使用。例如,我们可以在 JSR233PostProcessor中使用以下代码的一些实例:

1-2.png

  又比如从 csv 文件中读取数据,并保存到一个list对象中:

1-3.png

  然后从其他取样器中使用这个对象:

1-4.png

  props变量

  props变量是JMeterProperties类的一个实例,它是一个Hashtable类型的对象,也可以存储String或Object类型的数据。props变量的作用域是全局的,也就是说,所有的线程组都可以访问和修改同一个props变量。如果不同的线程组需要共享数据,就可以使用props变量。

  props变量的使用方法和vars变量类似,我们可以在BeanShell Sampler或JSR223 Sampler中使用以下语法来获取和设置props变量:

  //获取props变量
  String value = props.get("key");
  Object obj = props.get("key");
  //设置props变量
  props.put("key", "value");
  props.put("key", new Object());

  我们也可以在其他元件中使用${__P(key)}来引用props变量的值。

  props变量的一个常见用途是保存一些全局配置参数,例如服务器地址,端口号等。例如,我们可以在Test Plan中使用User Defined Variables元件来定义一些props变量:

1-5.png

  然后,在其他地方,我们可以使用${__P(server)}来引用服务器地址。

  prev变量

  prev变量是SampleResult类的一个实例,它是一个对象,可以存储上一个请求(或者说上一个取样器)的结果信息。prev变量的作用域是当前线程组,并且只能在后置处理器(PostProcessor)或断言(Assertion)中使用。

  prev变量的使用方法是在BeanShell PostProcessor或JSR223 PostProcessor中使用以下语法来获取prev变量:

  SampleResult prev = ctx.getPreviousResult();

  然后,我们可以调用prev对象的各种方法来获取结果信息,例如:

1-6.png

1-7.png

  prev变量的一个常见用途是对上一个请求的结果进行处理或判断。例如,我们可以在BeanShell Assertion中使用以下代码来判断响应码是否为200:

  SampleResult prev = ctx.getPreviousResult();
  if (!"200".equals(prev.getResponseCode())) {
      AssertionResult result = new AssertionResult("检查检查状态码");
      result.setFailure(true);
      result.setFailureMessage("响应状态码鬼知道是啥,反正不是 200");
      prev.addAssertionResult(result);
      prev.setSuccessful(false);
  }

  当前了,你要是直接在jsr233或者beanshell中直接如下那样写,也不会出现错误,也能直接使用。

  //jsr233 中的代码
  def responseCode = prev.getResponseCode();

  sample变量

  sample变量是SampleEvent类的一个实例,它是一个对象,可以存储当前请求(或者说当前取样器)的事件信息。sample变量的作用域是当前线程组,能在监听器(Listener)中使用。

  sample变量的使用方法是在BeanShell Listener或JSR223 Listener中使用以下语法来获取sample变量:

  SampleEvent sample = ctx.getCurrentSampleEvent();

  然后,我们可以调用sample对象的各种方法来获取事件信息,例如:

  //获取取样器结果
  SampleResult result = sample.getResult();
  //获取线程名称
  String threadName = sample.getThreadName();
  //获取线程组名称
  String threadGroupName = sample.getThreadGroup();
  //获取主机名称
  String hostName = sample.getHostname();

  sample变量的一个常见用途是对当前请求的事件进行处理或记录。例如,我们可以在BeanShell Listener中使用以下代码来打印事件信息:

  SampleEvent sample = ctx.getCurrentSampleEvent();
  log.info("Thread name: " + sample.getThreadName());
  log.info("Thread group: " + sample.getThreadGroup());
  log.info("Host name: " + sample.getHostname());
  log.info("Sampler name: " + sample.getResult().getSampleLabel());
  log.info("Response time: " + sample.getResult().getTime());
  log.info("Response code: " + sample.getResult().getResponseCode());
  log.info("Response data: " + new String(sample.getResult().getResponseData()));

  内置变量的区别

  从上面的介绍可以看出,JMeter内置变量有以下几个区别:

  · vars和props都是Map类型的对象,可以存储和修改数据;prev和sample都是普通对象,只能读取数据。

  · vars和props都可以在任何地方引用;prev只能在后置处理器或断言中引用;sample只能在监听器中引用。

  · vars和props都需要手动设置和获取;prev和sample都由JMeter自动提供。

  · vars只能在当前线程组内共享;props可以跨线程组共享;prev和sample只能在当前线程内访问。

  · vars和props都只能存储String或Object类型;prev和sample都包含多种类型的数据。

  内置变量的实际工作场景

  来看一些实际工作场景:

  场景一:我们需要模拟用户上传文件,并且每个用户都要上传不同的文件。这时候,我们就可以使用JSR223 PreProcessor元件来动态生成一个文件名,并将它保存到props变量中。然后,在上传文件请求中,我们就可以使用${__P(filename)}来引用文件名。

  //在JSR223 PreProcessor的代码如下:
  import java.util.UUID
  //生成一个随机的UUID作为文件名
  String filename = UUID.randomUUID().toString() + ".txt"
  //将文件名保存到props变量中
  props.put("filename", filename)

  场景二:我们需要对每个请求的响应时间进行判断,如果超过了预期的时间,就要记录下来。这时候,我们就可以使用JSR223 Assertion元件来获取prev变量,并调用getTime()方法来获取响应时间。然后,我们就可以使用if语句来判断响应时间是否超过了预期,并使用log.info()方法来记录日志。

  //在JSR223 Assertion 中的代码如下:
  def prev = ctx.getPreviousResult()
  //获取响应时间
  def responseTime = prev.getTime()
  //设置预期时间为1000毫秒
  def expectedTime = 1000
  //判断响应时间是否超过预期
  if (responseTime > expectedTime) {
      // 这里建议将结果写入 csv 以便持久化查看
      log.info("响应时间是:${responseTime} ms, 预期时间是:${expectedTime} ms")
  }

  场景三:我们需要对每个请求的响应数据进行处理,如果包含了某些关键字,就要提取出来,那么则如下:

  //在JSR223 PostProcessor 中的代码如下:
  def prev = ctx.getPreviousResult()
  def responseData = prev.getResponseDataAsString()
  // 使用正则处理数据
  def regex = /<title>(.*?)<\/title>/
  def matcher = regex.matcher(responseData)
  if (matcher.find()) {
      def keyword = matcher.group(1)
      vars.put("keyword", keyword)
  }
  // 当然除了上述代码外,也可以直接使用正则匹配元件去处理。

  场景四:我们需要对每个请求的事件信息进行记录,例如线程名称,线程组名称,主机名称等,那么则如下:

  //在JSR223 Listener 中的代码
  def sample = ctx.getCurrentSampleEvent()
  def result = sample.getResult()
  //打印事件信息到日志文件中,建议处理到csv(不过会有一点性能开销)
  log.info("线程名称: " + sample.getThreadName())
  log.info("线程组名: " + sample.getThreadGroup())
  log.info("域名地址: " + sample.getHostname())
  log.info("取样器名: " + result.getSampleLabel())
  log.info("响应时间: " + result.getTime())
  log.info("响应编码: " + result.getResponseCode())
  log.info("响应数据: " + new String(result.getResponseData()))

作者:测试玩家勇哥    

来源:http://www.51testing.com/html/80/n-7797780.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 本文介绍如何打开IE和Chrome浏览器。web项目,需要做兼容性测试,最重要的是浏览器兼容性测试。如果只考虑windows平台,相信应该很多公司必须要测试IE、Firefox、Chrome这三大浏览器。所以webui 自动化测试,也需要在这三大浏览器上面运行和测试脚本。从前面文章,我们知道,要调用Firefox浏览器,我们需要下载geckodriver.exe这个文件,放到Python的安装路径下,例如在安装Python是默认安装,路径就是C:\Python27;同样的道理,如果要启动IE和谷歌浏览器,也需要下载相关的插件,放到Python安装路径(C:\Python27,和pyt...
            8 8 833
            分享
          • 读者提问:『性能测试准备测试数据,我是从数据库中把数据提取出来,放在 TXT 中,是否需要直接从数据库中访问数据,这两者得到的性能测试结果差异大吗,应该以哪个为准呢 ?』阿常回答:数据量较小的情况,数据放在 TXT 中或是从数据库中读取,区别不大。数据量较大的情况,从 TXT 读取内存消耗会很大,会影响性能,从而影响我们最终对服务器性能的判断了。另外,数据放在 TXT 中可能会存在数据格式转换的问题,直接读取数据库反而方便一点。阿常碎碎念:总结以上,数据量小两种方式皆可,数据量大建议读取数据库。看完今天的分享对你是不是有所启发呢,有任何想法都欢迎大家后台私信阿常,一起探讨交流
            0 0 841
            分享
          • 1.核心机制1.1.疑问:作用域有哪些?全局作用域的范围仅限于单个文件。在python中格式没有一个基于单个的、无所不包的情景文件的全局作用域。1.2.疑问:如何定义作用域?Def/class/lambda三种方式1.3.疑问:作用域的基本法则?LEGB法则L:本地作用域;E:上层结构中的本地作用域;G:全局作用域;B:内置作用域;法则描述:变量名引用分为四个作用域进行查找:LEGB,第一个能够完成查找的就算成功;默认状态下,变量名赋值会创建或者改变本地变量;全局声明将赋值变量名映射到模块文件内部的作用域;需要讲的就这么多^_^接下来,希望大家能自己慢慢去体会“引用”和“赋值”之间的区别,那将...
            13 13 1670
            分享
          • 要说测试人员职业生涯当中最在意也是最绕不开的一个终极话题就是如何和开发人员相处。相信很多测试人员在面试的时候也遇到过这个问题:你是如何 和开发人员相(si)处(bi)的呢?要说起测试人员和开发人员的博弈,就不得不提到一个著名的思维测试-囚徒困境。在这场著名的思维试验中,两个罪犯即两个同案犯被逮捕了,他们被分别关到两个牢房里接受审讯。他们都被告知:"如果你保持沉默,你会被判处一年徒刑;如果你出卖同伴,你会获得自由;但如果你的同伴出卖了你,你就会蹲两年大狱。"出于竞争性的私利"两个囚徒实际上都有动力去出卖对方。然而,就如同下图所显示的,如果两个囚徒互相出卖,则他们获得...
            1 0 3000
            分享
          • 问:你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决。首先,将问题提交到缺陷管理库里面进行备案。然后,要获取判断的依据和标准:根据需求说明书、产品说明、设计文档等,确认实际结果是否与计划有不一致的地方,提供缺陷是否确认的直接依据;如果没有文档依据,可以根据类似软件的一般特性来说明是否存在不一致的地方,来确认是否是缺陷;根据用户的一般使用习惯,来确认是否是缺陷;与设计人员、开发人员和客户代表等相关人员探讨,确认是否是缺陷;合理的论述,向测试经理说明自己的判断的理由,注意客观、严谨,不参杂个人情绪。等待测试经理做出最终决定,如果仍然存在争议,可以通过公司政策所提供的渠道...
            11 12 3101
            分享
      • 51testing软件测试圈微信