前文简述了通过后置处理器 - 正则表达式提取器 获取 HTTP请求 响应结果中的特定数据,未看过的亲,敬请参阅 JMeter学习-008-JMeter 后置处理器实例之 - 正则表达式提取器(一)。
此文主要对正则表达式提取器的 正则表达式、模板、匹配数字,三者的关系,做进一步的讲解。
截取商品列表响应结果数据中的一段商品数据如下所示:
{
"sysNo": "2142717",
"skuid": "487626525247",
"productID": "101-006-72958",
"productTitle": "苹果(Apple)iPhone 6 Plus (A1524) 16GB 金色 移动联通电信4G手机",
"price": "556600",
"activePrice": "",
"marketprice": "608800",
"promotionDesc": "A1524、A1586为三网通版,支持移动\/联通\/电信4G\/3G\/2G。找水货?找翻新?没有!易迅网为国行正品代言!!",
"manufacturerCode": "49",
"manufacturerName": "苹果(Apple)",
"evaluationNum": "1717",
"gradeNum": "48",
"onlineQty": "597",
"shippingday": "0t0",
"gift": 0,
"promotionType": "0",
"attribute": "20000000TD-SC(为保持美观,此行数据有所删除,不影响此文讲解,请知悉!)5.5寸三网通版",
"saleNum": "454",
"productTypeMasterid": "0",
"areaCode": "1",
"classid": "203320",
"tag": "超薄手机 大屏手机 待机时间长 高清屏 女神手机 拍照功能强 商务手机 外观漂亮 指纹识别 主流潮机",
"goodsUrl": "http:\/\/item.yixun.com\/item-2142717.html",
"picUrl": "http:\/\/img3.wgimg.com\/qqbuy\/2295220799\/item-00000000000000000000007188CE4A3F.0.jpg\/200?55DAE367",
"reachable": "0"
},
参照上述商品信息数据,假定我们需要获取的是商品的系统编号、商品价格,那么我们改如何写呢?对应上述信息获取商品系统编号、商品销售价格,最终的正则表达式如下所示:
单独获取商品系统编号:
单独获取商品销售价格:
执行结果如下所示:
price=556600 price_g=1 price_g0="price":"556600"," price_g1=556600 sysNo=2142717 sysNo_g=1 sysNo_g0="sysNo":"2142717"," sysNo_g1=2142717
在前文的讲述中,正则表达式提取器的模板是匹配正则表达式提取式的控制模板。例如:模板 $1$ 中的数字 1 代表取第一个正则提取式的内容,当为0时,为整个正则表达式完整匹配项。那么我们就可以通过模板控制我们选取的提取式,以获取相应的内容,进行相应的后续操作。通过模板控制,单独获取商品系统编号、销售价格的正则表达式提取配置如下所示:
混合单取商品系统编号:
混合单取商品销售价格:
执行结果如下所示:
single_price=556600 single_price_g=2 single_price_g0=sysNo":"2142717","skuid":"487626525247","productID":"101-006-72958","productTitle":"苹果(Apple)iPhone 6 Plus (A1524) 16GB 金色 移动联通电信4G手机","price":"556600"," single_price_g1=2142717 single_price_g2=556600 single_sysNo=2142717 single_sysNo_g=2 single_sysNo_g0=sysNo":"2142717","skuid":"487626525247","productID":"101-006-72958","productTitle":"苹果(Apple)iPhone 6 Plus (A1524) 16GB 金色 移动联通电信4G手机","price":"556600"," single_sysNo_g1=2142717 single_sysNo_g2=556600
经过上述的讲解及演示,细心的小主可能已经发现了,在提取相关联的数据时,通过单独提取的方式非常的不方便,而且在数量多的时候,难免出现配置数据不对应的情况,造成所取的关联数据并非关联数据。那么针对此种情况,我们改如何处理呢?通过 上篇文章 及本文前面的讲解,我们知道,既然可以通过模板控制提取内容的选取,那是否可将相关联的需提取的内容同时在一个正则表达式提取器中完成呢?答案是可以的,仅需在引用名称、模板、匹配数字、缺省值 进行相应的配置即可,同时以英文半角字符 “,” 分隔即可。下面就以同时获取系统编号和销售价格为例进行演示:
正则提取器配置如下所示:
执行结果如下所示:
goodInfo=2142711,558800 goodInfo_g=2 goodInfo_g0=sysNo":"2142711","skuid":"487626066110","productID":"101-006-69384","productTitle":"苹果(Apple)iPhone 6 Plus (A1524) 16GB 深空灰色 移动联通电信4G手机","price":"558800"," goodInfo_g1=2142711 goodInfo_g2=558800
附录(1)- JMeter测试脚本:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <jmeterTestPlan version="1.2" properties="2.7" jmeter="2.12 r1636949"> 3 <hashTree> 4 <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="接口自动化测试用例 - 非登录态" enabled="true"> 5 <stringProp name="TestPlan.comments"></stringProp> 6 <boolProp name="TestPlan.functional_mode">false</boolProp> 7 <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> 8 <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true"> 9 <collectionProp name="Arguments.arguments"/> 10 </elementProp> 11 <stringProp name="TestPlan.user_define_classpath"></stringProp> 12 </TestPlan> 13 <hashTree> 14 <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="001-类目搜索验证" enabled="true"> 15 <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> 16 <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> 17 <boolProp name="LoopController.continue_forever">false</boolProp> 18 <stringProp name="LoopController.loops">1</stringProp> 19 </elementProp> 20 <stringProp name="ThreadGroup.num_threads">1</stringProp> 21 <stringProp name="ThreadGroup.ramp_time">1</stringProp> 22 <longProp name="ThreadGroup.start_time">1419564228000</longProp> 23 <longProp name="ThreadGroup.end_time">1419564228000</longProp> 24 <boolProp name="ThreadGroup.scheduler">false</boolProp> 25 <stringProp name="ThreadGroup.duration"></stringProp> 26 <stringProp name="ThreadGroup.delay"></stringProp> 27 </ThreadGroup> 28 <hashTree> 29 <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="手机数码-手机通讯-苹果" enabled="true"> 30 <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> 31 <collectionProp name="Arguments.arguments"> 32 <elementProp name="districtId" elementType="HTTPArgument"> 33 <boolProp name="HTTPArgument.always_encode">false</boolProp> 34 <stringProp name="Argument.name">districtId</stringProp> 35 <stringProp name="Argument.value">29357</stringProp> 36 <stringProp name="Argument.metadata">=</stringProp> 37 <boolProp name="HTTPArgument.use_equals">true</boolProp> 38 </elementProp> 39 <elementProp name="exAppTag" elementType="HTTPArgument"> 40 <boolProp name="HTTPArgument.always_encode">false</boolProp> 41 <stringProp name="Argument.name">exAppTag</stringProp> 42 <stringProp name="Argument.value">2045191607</stringProp> 43 <stringProp name="Argument.metadata">=</stringProp> 44 <boolProp name="HTTPArgument.use_equals">true</boolProp> 45 </elementProp> 46 </collectionProp> 47 </elementProp> 48 <stringProp name="HTTPSampler.domain">mb.51buy.com</stringProp> 49 <stringProp name="HTTPSampler.port"></stringProp> 50 <stringProp name="HTTPSampler.connect_timeout"></stringProp> 51 <stringProp name="HTTPSampler.response_timeout"></stringProp> 52 <stringProp name="HTTPSampler.protocol">http</stringProp> 53 <stringProp name="HTTPSampler.contentEncoding">GB2312</stringProp> 54 <stringProp name="HTTPSampler.path">/json.php?mod=Search&act=page&p=1&path=706188t706189&districtId=29357&areacode=1&dtype=list%7Cpage%7Cclasses&appSource=android&appVersion=45</stringProp> 55 <stringProp name="HTTPSampler.method">POST</stringProp> 56 <boolProp name="HTTPSampler.follow_redirects">true</boolProp> 57 <boolProp name="HTTPSampler.auto_redirects">false</boolProp> 58 <boolProp name="HTTPSampler.use_keepalive">true</boolProp> 59 <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> 60 <boolProp name="HTTPSampler.monitor">false</boolProp> 61 <stringProp name="HTTPSampler.embedded_url_re"></stringProp> 62 </HTTPSamplerProxy> 63 <hashTree> 64 <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> 65 <collectionProp name="HeaderManager.headers"> 66 <elementProp name="Charset" elementType="Header"> 67 <stringProp name="Header.name">Charset</stringProp> 68 <stringProp name="Header.value">UTF-8</stringProp> 69 </elementProp> 70 <elementProp name="Content-Type" elementType="Header"> 71 <stringProp name="Header.name">Content-Type</stringProp> 72 <stringProp name="Header.value">application/x-www-form-urlencoded</stringProp> 73 </elementProp> 74 <elementProp name="Accept-Encoding" elementType="Header"> 75 <stringProp name="Header.name">Accept-Encoding</stringProp> 76 <stringProp name="Header.value">gzip</stringProp> 77 </elementProp> 78 <elementProp name="User-Agent" elementType="Header"> 79 <stringProp name="Header.name">User-Agent</stringProp> 80 <stringProp name="Header.value">Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-I9502 Build/KOT49H)</stringProp> 81 </elementProp> 82 </collectionProp> 83 </HeaderManager> 84 <hashTree/> 85 <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="01 - 判断类目搜索结果状态码" enabled="true"> 86 <collectionProp name="Asserion.test_strings"> 87 <stringProp name="71131476">"errno":0</stringProp> 88 </collectionProp> 89 <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> 90 <boolProp name="Assertion.assume_success">false</boolProp> 91 <intProp name="Assertion.test_type">2</intProp> 92 </ResponseAssertion> 93 <hashTree/> 94 <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则表达式提取器 - 获取商品列表中商品的系统编号" enabled="true"> 95 <stringProp name="RegexExtractor.useHeaders">false</stringProp> 96 <stringProp name="RegexExtractor.refname">sysNo</stringProp> 97 <stringProp name="RegexExtractor.regex">"sysNo":"(.+?)","</stringProp> 98 <stringProp name="RegexExtractor.template">$1$</stringProp> 99 <stringProp name="RegexExtractor.default">ERROR</stringProp> 100 <stringProp name="RegexExtractor.match_number">2</stringProp> 101 </RegexExtractor> 102 <hashTree/> 103 <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则表达式提取器 - 获取商品列表中商品的销售价格" enabled="true"> 104 <stringProp name="RegexExtractor.useHeaders">false</stringProp> 105 <stringProp name="RegexExtractor.refname">price</stringProp> 106 <stringProp name="RegexExtractor.regex">"price":"(.+?)","</stringProp> 107 <stringProp name="RegexExtractor.template">$1$</stringProp> 108 <stringProp name="RegexExtractor.default">ERROR</stringProp> 109 <stringProp name="RegexExtractor.match_number">2</stringProp> 110 </RegexExtractor> 111 <hashTree/> 112 <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则表达式提取器 - 多匹配项处理之一 - 获取单个匹配项" enabled="true"> 113 <stringProp name="RegexExtractor.useHeaders">false</stringProp> 114 <stringProp name="RegexExtractor.refname">single_sysNo</stringProp> 115 <stringProp name="RegexExtractor.regex">sysNo":"([0-9]{2,8}).+?price":"(.+?)","</stringProp> 116 <stringProp name="RegexExtractor.template">$1$</stringProp> 117 <stringProp name="RegexExtractor.default">ERROR</stringProp> 118 <stringProp name="RegexExtractor.match_number">2</stringProp> 119 </RegexExtractor> 120 <hashTree/> 121 <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则表达式提取器 - 多匹配项处理之二 - 获取单个匹配项" enabled="true"> 122 <stringProp name="RegexExtractor.useHeaders">false</stringProp> 123 <stringProp name="RegexExtractor.refname">single_price</stringProp> 124 <stringProp name="RegexExtractor.regex">sysNo":"([0-9]{2,8}).+?price":"(.+?)","</stringProp> 125 <stringProp name="RegexExtractor.template">$2$</stringProp> 126 <stringProp name="RegexExtractor.default">ERROR</stringProp> 127 <stringProp name="RegexExtractor.match_number">2</stringProp> 128 </RegexExtractor> 129 <hashTree/> 130 <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则表达式提取器 - 多匹配项处理之三 - 获取多个匹配项" enabled="true"> 131 <stringProp name="RegexExtractor.useHeaders">false</stringProp> 132 <stringProp name="RegexExtractor.refname">multi_sysNo,multi_price</stringProp> 133 <stringProp name="RegexExtractor.regex">sysNo":"([0-9]{2,8}).+?price":"(.+?)","</stringProp> 134 <stringProp name="RegexExtractor.template">$1$,$2$</stringProp> 135 <stringProp name="RegexExtractor.default">ERROR,ERROR</stringProp> 136 <stringProp name="RegexExtractor.match_number">3,3</stringProp> 137 </RegexExtractor> 138 <hashTree/> 139 <DebugPostProcessor guiclass="TestBeanGUI" testclass="DebugPostProcessor" testname="DPP -- 所属 :HTTP请求" enabled="true"> 140 <boolProp name="displayJMeterProperties">false</boolProp> 141 <boolProp name="displayJMeterVariables">true</boolProp> 142 <boolProp name="displaySamplerProperties">true</boolProp> 143 <boolProp name="displaySystemProperties">false</boolProp> 144 </DebugPostProcessor> 145 <hashTree/> 146 </hashTree> 147 </hashTree> 148 <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="察看结果树" enabled="true"> 149 <boolProp name="ResultCollector.error_logging">false</boolProp> 150 <objProp> 151 <name>saveConfig</name> 152 <value class="SampleSaveConfiguration"> 153 <time>true</time> 154 <latency>true</latency> 155 <timestamp>true</timestamp> 156 <success>true</success> 157 <label>true</label> 158 <code>true</code> 159 <message>true</message> 160 <threadName>true</threadName> 161 <dataType>true</dataType> 162 <encoding>false</encoding> 163 <assertions>true</assertions> 164 <subresults>true</subresults> 165 <responseData>false</responseData> 166 <samplerData>false</samplerData> 167 <xml>false</xml> 168 <fieldNames>false</fieldNames> 169 <responseHeaders>false</responseHeaders> 170 <requestHeaders>false</requestHeaders> 171 <responseDataOnError>false</responseDataOnError> 172 <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage> 173 <assertionsResultsToSave>0</assertionsResultsToSave> 174 <bytes>true</bytes> 175 <threadCounts>true</threadCounts> 176 </value> 177 </objProp> 178 <stringProp name="filename"></stringProp> 179 </ResultCollector> 180 <hashTree/> 181 </hashTree> 182 </hashTree> 183 </jmeterTestPlan>