在我的 JMeter 场景中,我正在测试 SOAP Web 服务。我将初始请求发送到 Web 服务 S1,然后使用它的响应来构建对 S2 的请求。S1 的响应采用以下形式:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<s:response xmlns:s="http://custom.namespace.com/namespace">
...
<s:responseDetails>
<s:detail1>some info</s:detail>
<s:detail2>another info<s:detail2>
...
</s:responseDetails>
</s:response>
</soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)
我需要使用里面的所有内容<s:responseDetails>来构建对 S2 的请求,但包装在不同的 xml 元素中:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://custom.namespace.com/namespace">
<soap:Body>
<s:request>
<s:details>
<s:detail1>some info</s:detail>
<s:detail2>another info<s:detail2>
...
</s:details>
</s:request>
</soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)
注意<s:details>请求中的元素而不是<s:responseDetails>.
我从 XPath 提取器开始,希望使用 XPath 表达式将<s:responseDetails>标记下的所有内容放入 JMeter 变量中:
//*[local-name()='responseDetails']/node()- 给我一组具有不同子代的 JMeter 变量<s:responseDetails>,而我希望它们位于一个变量中//*[local-name()='responseDetails']<s:responseDetails>- 给了我由于根标签的存在而无法使用的整个节点<s:responseDetails>,我需要将其替换为<s:details>将所有内容放入<s:responseDetails>变量中的正确表达式是什么,以便我以后可以使用
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://custom.namespace.com/namespace">
<soap:Body>
<s:request>
<s:details>
${details}
</s:details>
</s:request>
</soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)
或者也许有另一种方法可以解决我的问题?
请执行下列操作:
1) 添加 XPath Extractor,就像您所做的那样:
2) 添加 Beanshell 采样器:
String fragment = vars.get("responseFragment");
// Improve this replacement by regexp to avoid side effects
String newFragment = fragment.replace("responseDetails","details");
vars.put("modifiedFragment", newFragment);
Run Code Online (Sandbox Code Playgroud)
3)然后使用:${modifiedFragment}
请注意,Beanshell 采样器会稍微降低 JMeter 的性能,但这应该是合理的。
请注意,您可以将 Beanshell 采样器替换为 JSR 223,并在外部文件中使用 groovy 底层语言和脚本。
使用 JMeter > 2.7 版本的性能将比 beanshell 解决方案更好,因为新版本的 JMeter 引入了新的缓存机制,该机制将“编译”Groovy 脚本并使其几乎与 Java 类一样高效。
自 2012 年 9 月 3 日起,该机制在JMeter Nightly build中可用。
JMeter 测试计划示例:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.3" jmeter="2.8-SNAPSHOT.20120903">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</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="Thread Group" 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">1346673693000</longProp>
<longProp name="ThreadGroup.end_time">1346673693000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Java Request" enabled="true">
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="Sleep_Time" elementType="Argument">
<stringProp name="Argument.name">Sleep_Time</stringProp>
<stringProp name="Argument.value">100</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="Sleep_Mask" elementType="Argument">
<stringProp name="Argument.name">Sleep_Mask</stringProp>
<stringProp name="Argument.value">0xFF</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="Label" elementType="Argument">
<stringProp name="Argument.name">Label</stringProp>
<stringProp name="Argument.value">OK</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="ResponseCode" elementType="Argument">
<stringProp name="Argument.name">ResponseCode</stringProp>
<stringProp name="Argument.value">200</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="ResponseMessage" elementType="Argument">
<stringProp name="Argument.name">ResponseMessage</stringProp>
<stringProp name="Argument.value">200</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="Status" elementType="Argument">
<stringProp name="Argument.name">Status</stringProp>
<stringProp name="Argument.value">OK</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="SamplerData" elementType="Argument">
<stringProp name="Argument.name">SamplerData</stringProp>
<stringProp name="Argument.value"></stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="ResultData" elementType="Argument">
<stringProp name="Argument.name">ResultData</stringProp>
<stringProp name="Argument.value"><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <s:response xmlns:s="http://custom.namespace.com/namespace"> <s:responseDetails> <s:detail1>some info</s:detail1> <s:detail2>another info</s:detail2> </s:responseDetails> </s:response> </soap:Body> </soap:Envelope></stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="classname">org.apache.jmeter.protocol.java.test.JavaTest</stringProp>
</JavaSampler>
<hashTree>
<XPathExtractor guiclass="XPathExtractorGui" testclass="XPathExtractor" testname="XPath Extractor" enabled="true">
<stringProp name="XPathExtractor.default"></stringProp>
<stringProp name="XPathExtractor.refname">TOTO</stringProp>
<stringProp name="XPathExtractor.xpathQuery">//s:response/s:responseDetails</stringProp>
<boolProp name="XPathExtractor.validate">false</boolProp>
<boolProp name="XPathExtractor.tolerant">false</boolProp>
<boolProp name="XPathExtractor.namespace">true</boolProp>
<boolProp name="XPathExtractor.whitespace">true</boolProp>
</XPathExtractor>
<hashTree/>
</hashTree>
<DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Debug Sampler" enabled="true">
<boolProp name="displayJMeterProperties">false</boolProp>
<boolProp name="displayJMeterVariables">true</boolProp>
<boolProp name="displaySystemProperties">false</boolProp>
</DebugSampler>
<hashTree/>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" 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>false</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>false</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
Run Code Online (Sandbox Code Playgroud)
其他方式:
1) 添加 XPath Extractor,就像您所做的那样:
2) 添加 Beanshell 采样器:
int number = Integer.parseInt(vars.get("fullAnswer_matchNr"));
StringBuilder builder = new StringBuilder();
for(int i=0;i<number;i++) {
builder.append(vars.get("fullAnswer_"+(i+1)));
}
vars.put("body", builder.toString());
Run Code Online (Sandbox Code Playgroud)
3)使用本体
这个更干净一点,因为没有替代品
| 归档时间: |
|
| 查看次数: |
7144 次 |
| 最近记录: |