JMeter预处理变量作为报告文件名的一部分 [英] JMeter pre-processed variable as part of report file name

查看:130
本文介绍了JMeter预处理变量作为报告文件名的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的测试计划中,我有JDBC PreProcessor,它捕获了我要保存到变量中的单个值.然后,我想将此变量作为摘要报告的文件名的一部分重用.

In my test plan I have JDBC PreProcessor that captures a single value that I'm trying to save into a variable. Then I want to reuse this variable as part of summary report's file name.

我想知道创建该变量是否为时已晚,因为我总是得到文字值logs/${session_id_1}-summary.cvs而不是logs/1234-summary.cvs

I wonder if creating that creating that variable happens too late because I always get literal value logs/${session_id_1}-summary.cvs rather than logs/1234-summary.cvs

我也不确定是否需要使用resultVariablevariableNames来存储值.到目前为止,我没有运气尝试过不同的组合

I'm also not sure if I need to use resultVariable or variableNames to store the value. So far I tried different combinations with no luck

然后我也不清楚应该在哪一点上将预处理器连接到第一个采样器?

Then I'm also not clear at which point I should attach the pre-processor, to the first sampler?

这是我最新的(简短)JMX版本:

Here's my latest (short) version of JMX:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.9" jmeter="3.0 r1743807">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="TPCDS Benchmark Test Plan TPG Flavor" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">true</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="JDBC Users" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <longProp name="ThreadGroup.start_time">1370729701000</longProp>
        <longProp name="ThreadGroup.end_time">1370729701000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <JDBCDataSource guiclass="TestBeanGUI" testclass="JDBCDataSource" testname="JDBC_Configuration_tpcds" enabled="true">
          <boolProp name="autocommit">true</boolProp>
          <stringProp name="checkQuery">Select 1</stringProp>
          <stringProp name="connectionAge">5000</stringProp>
          <stringProp name="dataSource">jdbcConfig_tpcds</stringProp>
          <stringProp name="dbUrl">jdbc:teradata://${TDPID}/database=tpcds</stringProp>
          <stringProp name="driver">com.teradata.jdbc.TeraDriver</stringProp>
          <boolProp name="keepAlive">true</boolProp>
          <stringProp name="password">tpcds</stringProp>
          <stringProp name="poolMax">10</stringProp>
          <stringProp name="timeout">10000</stringProp>
          <stringProp name="transactionIsolation">DEFAULT</stringProp>
          <stringProp name="trimInterval">60000</stringProp>
          <stringProp name="username">tpcds</stringProp>
        </JDBCDataSource>
        <hashTree/>
        <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
          <collectionProp name="Arguments.arguments">
            <elementProp name="TDPID" elementType="Argument">
              <stringProp name="Argument.name">TDPID</stringProp>
              <stringProp name="Argument.value">${__P(target_dbs)}</stringProp>
              <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>
            <elementProp name="DBC_USERNAME" elementType="Argument">
              <stringProp name="Argument.name">DBC_USERNAME</stringProp>
              <stringProp name="Argument.value">${__P(dbc_username,dbc)}</stringProp>
              <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>
            <elementProp name="DBC_PASSWORD" elementType="Argument">
              <stringProp name="Argument.name">DBC_PASSWORD</stringProp>
              <stringProp name="Argument.value">${__P(dbc_password,dbc)}</stringProp>
              <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>
          </collectionProp>
        </Arguments>
        <hashTree/>
        <JDBCSampler guiclass="TestBeanGUI" testclass="JDBCSampler" testname="query1" enabled="true">
          <stringProp name="dataSource">jdbcConfig_tpcds</stringProp>
          <stringProp name="query">${__FileToString(sql/query1.sql)}</stringProp>
          <stringProp name="queryArguments"></stringProp>
          <stringProp name="queryArgumentsTypes"></stringProp>
          <stringProp name="queryType">Select Statement</stringProp>
          <stringProp name="resultVariable"></stringProp>
          <stringProp name="variableNames"></stringProp>
          <stringProp name="queryTimeout"></stringProp>
          <stringProp name="resultSetHandler">Store as String</stringProp>
        </JDBCSampler>
        <hashTree>
          <JDBCPreProcessor guiclass="TestBeanGUI" testclass="JDBCPreProcessor" testname="Session PreProcessor" enabled="true">
            <stringProp name="dataSource">jdbcConfig_tpcds</stringProp>
            <stringProp name="query">SELECT SESSION as session_id;</stringProp>
            <stringProp name="queryArguments"></stringProp>
            <stringProp name="queryArgumentsTypes"></stringProp>
            <stringProp name="queryTimeout"></stringProp>
            <stringProp name="queryType">Select Statement</stringProp>
            <stringProp name="resultSetHandler">Store as String</stringProp>
            <stringProp name="resultVariable">session_id</stringProp>
            <stringProp name="variableNames">session_id</stringProp>
          </JDBCPreProcessor>
          <hashTree/>
        </hashTree>
        <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>false</assertions>
              <subresults>false</subresults>
              <responseData>true</responseData>
              <samplerData>false</samplerData>
              <xml>true</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename">logs/${session_id_1}-summary.xml</stringProp>
        </ResultCollector>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

推荐答案

在JMeter中实际上不支持动态更改侦听器测试元素的文件名,因为在任何变量之前 都已初始化了侦听器.推荐的方法是:

Changing filenames of Listeners test elements on the fly is not really supported in JMeter as Listeners are being initialized before any variables. The recommended way is:

  1. 在JMeter之外获取您的Terradata会话ID,即使用 BTEQ 或等效的
  2. 通过-J命令行参数将值传递给JMeter:

  1. Get your Terradata session id outside of JMeter, i.e. using BTEQ or equivalent
  2. Pass the value to JMeter via -J command line argument like:

jmeter -Jsession_id_1=1234 -n -t /path/to/testplan.jmx

  • 通过 __P()函数引用会话ID值,其中要求为

  • Refer the session id value via __P() function where required as

    ${__P(session_id_1,)}
    


  • 如果出于任何原因仍然需要在JMeter测试脚本中执行此操作,则可以采用以下解决方案,但是请记住以下几点:


    If for any reason you still need to do it inside JMeter test script, here is a possible solution, however keep in mind the following:

    1. 您需要从摘要报告"侦听器的文件名"输入中删除所有内容.只是让它空白.
    2. 确保以下代码仅一次执行且仅使用一个线程执行一次.
    1. You need to remove everything from "Filename" input of the Summary Report listener. Just let it be blank.
    2. Make sure that below code is executed only once and with only one thread.

    所以:

    1. JSR223 PostProcessor 添加为query1采样器和<在Session PreProcessor
    2. 之后
    3. 在语言"下拉列表中选择groovy
    4. 将以下代码放入JSR223 PostProcessor脚本"区域:

    1. Add JSR223 PostProcessor as a child of the query1 sampler and after the Session PreProcessor
    2. Select groovy in the "Language" drop-down
    3. Put the following code into JSR223 PostProcessor "Script" area:

    import org.apache.jmeter.engine.StandardJMeterEngine;
    import org.apache.jmeter.reporters.ResultCollector;
    import org.apache.jorphan.collections.HashTree;
    import org.apache.jorphan.collections.SearchByClass;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    StandardJMeterEngine engine = ctx.getEngine();
    Field test = engine.getClass().getDeclaredField("test");
    test.setAccessible(true);
    HashTree testPlanTree = (HashTree) test.get(engine);        
    
    SearchByClass summaryReportsSearch = new SearchByClass(ResultCollector.class);
    testPlanTree.traverse(summaryReportsSearch);
    Collection summaryReports = summaryReportsSearch.getSearchResults();
    ResultCollector summaryReport = summaryReports.iterator().next();
    
    Class [] fileNameParam = new Class[1];
    fileNameParam[0] = String.class;
    
    Method setFileName = summaryReport.getClass().getDeclaredMethod("setFilenameProperty", fileNameParam);
    setFileName.setAccessible(true);
    setFileName.invoke(summaryReport, new String(vars.get("session_id_1")));
    
    Method init = summaryReport.getClass().getDeclaredMethod("initializeFileOutput");
    init.setAccessible(true);
    init.invoke(summaryReport);
    

    如果您使用的是JMeter 3.0,则groovy已捆绑.对于以前的JMeter版本,您将需要手动安装Groovy语言支持,请查看

    If you're using JMeter 3.0 - groovy is bundled. For previous JMeter versions you will need to install groovy language support manually, check out Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! article for groovy engine installation instructions and scripting best practices.

    这篇关于JMeter预处理变量作为报告文件名的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆