小编典典

JMeter预处理变量作为报告文件名的一部分

sql

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

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

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

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

这是我最新的(简短)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>

阅读 192

收藏
2021-03-23

共1个答案

小编典典

JMeter并不真正支持即时更改侦听器测试元素的文件名,因为侦听器会 任何变量 之前 初始化。推荐的方式是:

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

    jmeter -Jsession_id_1=1234 -n -t /path/to/testplan.jmx
    
  3. 在需要时通过__P()函数引用会话ID值

    ${__P(session_id_1,)}
    

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

  1. 您需要从“摘要报告”侦听器的“文件名”输入中删除 所有内容 。只是让它空白。
  2. 确保下面的代码仅执行 一次 且只有一个线程。

所以:

  1. 添加JSR223 PostProcessor中的一个子query1采样和 之后Session PreProcessor
  2. 选择groovy在“语言”下拉列表
  3. 将以下代码放入JSR223 PostProcessor“脚本”区域:

    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语言支持,请查看Beanshell,JSR223和Java
JMeter脚本:您一直在等待的性能!
有关groovy引擎安装说明和脚本编写最佳实践的文章。

2021-03-23