JMeter学习-007-JMeter 断言实例之一 - 响应断言

之前的文章中已经对如何录制 web 的请求进行了详细的描述,敬请参阅:JMeter学习-004-WEB脚本入门实战

同时,我们的手机应用(例如:京东、天猫、唯品会、携程、易迅 等等 App)所发出的请求,也可进行录制,只需要将手机连接的无线网络代理到本机(以 iPhone 为例,依次点击 【设置】/【无线局域网】/【连接网络信息,即网络右侧详细信息符号】/【HTTP代理】/手动】,填写 服务器IP、端口 对应填写 JMeter 机器的 IP、JMeter HTTP 代理端口 即可),并将对应的端口设置为 JMeter 中设置的端口后,即可对相应的操作进行录制操作。非常简单,在此不再赘述。

当我们执行脚本的时候,需要依据一定的条件去判断脚本是否执行成功,例如响应信息(响应头、主体、响应数据、响应代码、大小等)、响应时间。JMeter 中也响应的给我们提供了相应的断言,大多数通用的断言 JMeter 均已给出,例如:Response Assertion、Size Assertion、MD5Hex Assertion等等。JMeter 提供的断言列表如下所示:

以下就以易迅网App的一个简单的类目搜索,对其添加响应断言和大小断言,来简单的演示一下 JMeter 中的断言。具体的操作步骤如下:

  1. 获取类目 手机数码-手机通讯-苹果 的 HTTP 请求(通过 JMeter HTTP代理服务器 录制即可获得,在此略)
  2. 添加如下所示 Response Assertion(前四)、Size Assertion(后一):
    1. 01 - 判断类目搜索结果状态码
    2. 02 - 判断类目搜索结果响应数据包含苹果
    3. 03 - 判断类目搜索结果中不包含信息
    4. 04 - 判断类目搜索结果响应头信息中包含 Server: nginx
    5. 05 - 判断响应结果大小(body)
  3. 添加查看结果树

添加响应断言:

右键单击 HTTP请求(手机数码-手机通讯-苹果),依次选择:【添加/断言/响应断言】,如下图所示:

响应断言添加页面如下所示:

要测试的响应字段:取样区域,也可简单理解为取样的数据源。单选 与 复选按钮可同时选择。

模式匹配规则:判断的关系依据。单选 与 复选按钮可同时选择,选择了复选框后,为前面关系条件的否。例如前面选择了 包括,同时勾选了 否,则实际判断关系依据为:不包括。

要测试的模式:可简单理解为判断的值。

PS:一个断言仅可判断一种类型的断言,无法混杂判断,即 要测试的响应字段、模式匹配规则、要测试的模式 在此断言中都是相同,若模式匹配规则不同,则需新增响应断言。

最终的脚本样式如下所示:

脚本源码为:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

<?xml version="1.0" encoding="UTF-8"?>

<jmeterTestPlan version="1.2" properties="2.8" jmeter="2.13 r1665067">

  <hashTree>

    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="接口自动化测试用例 - 非登录态" 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="用户定义的变量" enabled="true">

        <collectionProp name="Arguments.arguments"/>

      </elementProp>

      <stringProp name="TestPlan.user_define_classpath"></stringProp>

    </TestPlan>

    <hashTree>

      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="001-类目搜索验证" enabled="true">

        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>

        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" 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">1419564228000</longProp>

        <longProp name="ThreadGroup.end_time">1419564228000</longProp>

        <boolProp name="ThreadGroup.scheduler">false</boolProp>

        <stringProp name="ThreadGroup.duration"></stringProp>

        <stringProp name="ThreadGroup.delay"></stringProp>

      </ThreadGroup>

      <hashTree>

        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="手机数码-手机通讯-苹果" enabled="true">

          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">

            <collectionProp name="Arguments.arguments">

              <elementProp name="districtId" elementType="HTTPArgument">

                <boolProp name="HTTPArgument.always_encode">false</boolProp>

                <stringProp name="Argument.name">districtId</stringProp>

                <stringProp name="Argument.value">29357</stringProp>

                <stringProp name="Argument.metadata">=</stringProp>

                <boolProp name="HTTPArgument.use_equals">true</boolProp>

              </elementProp>

              <elementProp name="exAppTag" elementType="HTTPArgument">

                <boolProp name="HTTPArgument.always_encode">false</boolProp>

                <stringProp name="Argument.name">exAppTag</stringProp>

                <stringProp name="Argument.value">2045191607</stringProp>

                <stringProp name="Argument.metadata">=</stringProp>

                <boolProp name="HTTPArgument.use_equals">true</boolProp>

              </elementProp>

            </collectionProp>

          </elementProp>

          <stringProp name="HTTPSampler.domain">mb.51buy.com</stringProp>

          <stringProp name="HTTPSampler.port"></stringProp>

          <stringProp name="HTTPSampler.connect_timeout"></stringProp>

          <stringProp name="HTTPSampler.response_timeout"></stringProp>

          <stringProp name="HTTPSampler.protocol">http</stringProp>

          <stringProp name="HTTPSampler.contentEncoding">GB2312</stringProp>

          <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>

          <stringProp name="HTTPSampler.method">POST</stringProp>

          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>

          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>

          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>

          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>

          <boolProp name="HTTPSampler.monitor">false</boolProp>

          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>

        </HTTPSamplerProxy>

        <hashTree>

          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true">

            <collectionProp name="HeaderManager.headers">

              <elementProp name="Charset" elementType="Header">

                <stringProp name="Header.name">Charset</stringProp>

                <stringProp name="Header.value">UTF-8</stringProp>

              </elementProp>

              <elementProp name="Content-Type" elementType="Header">

                <stringProp name="Header.name">Content-Type</stringProp>

                <stringProp name="Header.value">application/x-www-form-urlencoded</stringProp>

              </elementProp>

              <elementProp name="Accept-Encoding" elementType="Header">

                <stringProp name="Header.name">Accept-Encoding</stringProp>

                <stringProp name="Header.value">gzip</stringProp>

              </elementProp>

              <elementProp name="User-Agent" elementType="Header">

                <stringProp name="Header.name">User-Agent</stringProp>

                <stringProp name="Header.value">Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-I9502 Build/KOT49H)</stringProp>

              </elementProp>

            </collectionProp>

          </HeaderManager>

          <hashTree/>

          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="01 - 判断类目搜索结果状态码" enabled="true">

            <collectionProp name="Asserion.test_strings">

              <stringProp name="71131476">"errno":0</stringProp>

            </collectionProp>

            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>

            <boolProp name="Assertion.assume_success">false</boolProp>

            <intProp name="Assertion.test_type">2</intProp>

          </ResponseAssertion>

          <hashTree/>

          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="02 - 判断类目搜索结果响应数据包含苹果" enabled="true">

            <collectionProp name="Asserion.test_strings">

              <stringProp name="1065923">苹果</stringProp>

            </collectionProp>

            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>

            <boolProp name="Assertion.assume_success">false</boolProp>

            <intProp name="Assertion.test_type">2</intProp>

          </ResponseAssertion>

          <hashTree/>

          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="03 - 判断类目搜索结果中不包含信息" enabled="true">

            <collectionProp name="Asserion.test_strings">

              <stringProp name="1425729940">我的博客地址: http://www.cnblogs.com/fengpingfan/</stringProp>

            </collectionProp>

            <stringProp name="Assertion.test_field">Assertion.response_headers</stringProp>

            <boolProp name="Assertion.assume_success">false</boolProp>

            <intProp name="Assertion.test_type">6</intProp>

          </ResponseAssertion>

          <hashTree/>

          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="04 - 判断类目搜索结果响应头信息中包含 Server: nginx" enabled="true">

            <collectionProp name="Asserion.test_strings">

              <stringProp name="1066132337">Server: nginx</stringProp>

            </collectionProp>

            <stringProp name="Assertion.test_field">Assertion.response_headers</stringProp>

            <boolProp name="Assertion.assume_success">false</boolProp>

            <intProp name="Assertion.test_type">2</intProp>

          </ResponseAssertion>

          <hashTree/>

          <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="05 - 判断响应结果大小(body)" enabled="true">

            <stringProp name="Assertion.test_field">SizeAssertion.response_data</stringProp>

            <stringProp name="SizeAssertion.size">4000</stringProp>

            <intProp name="SizeAssertion.operator">3</intProp>

          </SizeAssertion>

          <hashTree/>

        </hashTree>

      </hashTree>

      <ResultCollector guiclass="AssertionVisualizer" testclass="ResultCollector" testname="断言结果" 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>true</assertions>

            <subresults>true</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>

            <threadCounts>true</threadCounts>

          </value>

        </objProp>

        <stringProp name="filename"></stringProp>

      </ResultCollector>

      <hashTree/>

      <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="察看结果树" 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>true</assertions>

            <subresults>true</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>

            <threadCounts>true</threadCounts>

          </value>

        </objProp>

        <stringProp name="filename"></stringProp>

      </ResultCollector>

      <hashTree/>

    </hashTree>

  </hashTree>

</jmeterTestPlan>

脚本执行结果如下所示:

那么当断言失败的时候是什么样子呢?我们依据下两图进行相应的修改:

在此执行的结果如下图所示,通过点击对应的断言,可查看断言的详细信息:

当然您也可以添加断言结果(右键单击测试计划、线程组、HTTP请求,以此选择【添加/监听器/断言结果】添加即可,注意断言结果的作用域,避免出现干扰),通过断言结果更加直观的查看所有的失败断言汇总信息,如下所示:

我们可以利用 JMeter 提供的各种断言,进行请求响应结果的判定,其他在本文中没有用到的断言,各位小主们可先自行研究探索。同时,在实际的自动化应用过程中,JMeter 的断言难免出现不满足我们测试场景的时候,那么就需要我们针对不同的场景进行扩展了,通过已有断言 BeanShell 和 BSF 去进行扩展,也许可以解决我们的问题。另外,JMeter 是用 Java 语言编写的开源测试工具,当然也具有 Java 良好的扩展性,我们可以通过开发 JMeter 插件对其进行符合我们当前业务的定制扩展,以大大提升适应性、易用性。(PS:相关的简单实战示例,后续陆续更新,敬请期待!)

至此, JMeter学习-006-JMeter 断言实例之一 - 响应断言 顺利完结,希望此文能够给初学 JMeter 的您一份参考。

最后,非常感谢亲的驻足,希望此文能对亲有所帮助。热烈欢迎亲一起探讨,共同进步。非常感谢! ^_^

时间: 2024-10-08 10:04:53

JMeter学习-007-JMeter 断言实例之一 - 响应断言的相关文章

JMeter学习-010-JMeter 配置元件实例之 - CSV Data Set Config 参数化配置

众所周知,在进行接口测试的过程中,需要创建不同的场景(不同条件的输入,来验证不同的入参的返回结果).因而,在日常的自动化接口监控或商品监控等线上监控过程中,需要配置大量的入参来监控接口的返回是否正确. 日常常见的线上监控几个简单的监控示例场景如下: 监控电商网站某个类目下的商品数量.若类目中商品的数量小于一定的数量,则认为需要认为查看商品池的商品是否正确: 监控商品的价格.当商品价格出现超出限定的波动幅度时,通知相应的商品负责人,对其进行确认,从而保证商品价格的正确无误. 监控商品在某一地域是否

JMeter断言处理之响应断言

在之前的文章中,已经学会了发送请求,那么,这个请求的结果是否正确呢?这个就需要使用JMeter的断言之响应断言了. 首先在JMeter中添加一个get请求,这里以中国天气网中获取深圳周边城市.深圳街道和深圳景点的标识码为例: 再添加查看结果树,发送请求,发现报403错误了,原因是接口对来源有防护,需要设置HTTP请求头,添加相应的内容: 这样我们就能获取到数据了,查看一下响应数据: 接下来,添加一个响应断言: 添加完断言后,我们再添加一个断言结果监听器: 运行,就能到断言结果页面查看到有一个请求

JMeter学习笔记--JMeter执行顺序规则

JMeter执行顺序规则: 配置元件 前置处理器 定时器 采样器 后置处理器(除非服务器响应为空) 断言 监听器 只有当作用域内存在采样器时,定时器.断言.前置/后置处理器才会被执行,逻辑控制器和采样器按照在测试树种出现的顺序执行.其他测试元件会依据自身的作用域来执行,另外与测试元件所属的类型有关(归属于同一类型的测试元件,会按照他们在测试树中出现的顺序来执行. 测试计划实例如下: Controller post-Processor1 Sampler1 Sampler2 Timer1 Asser

JMeter学习笔记--JMeter常用测试元件

JMeter测试计划有一个被称为“函数测试模式”的选项,如果被选择,它会使Jmeter记录来自服务器返回的每个取样的数据.如果你在测试监听器中选择一个文件,这个数据将被写入文件.如果你尝试一个较小的测试来保证Jmeter配置正确并且你的服务器正在返回期望的结果,这是很有用的.这样做的后果就是这个文件会快速的增大,并且Jmeter的效率会影响. 如果不记录数据到文件,这个选项就没有不同了. 线程组:是任何测试计划的起点,所有的逻辑控制器和采样器都必须放在线程组之下.其他的测试元件(如监听器)可以被

JMeter学习笔记--JMeter监听器

监听器(Listeners)是一种展示采样结果的测试元件,采样结果可以通过树.表格.图片加以展示,或者简单地写入某个结果文件之中. 注:不同的监听器通过不同的方式展示服务器响应信息,但它们都将同样的原始数据记录到某个输出文件中(在某个监听器中指定一个输出文件) ”Configure“ 按钮可以被用来配置哪些数据会被写入到结果文件之中,以及结果文件的格式CSV或者XML.与XML文件相比,csv文件占用的磁盘空间要小很多,当采样次数较多时,建议使用csv格式.另外测试人员可以使用简单控制器将一系列

JMeter学习笔记--JMeter属性和变量

JMeter属性统一定义在jmeter.properties文件中.JMeter属性在测试脚本的任何地方都是可见的(全局),通常被用来定义一些JMeter使用的默认值.如属性remote_hosts定义了JMeter在远程模式下运行的服务器地址.属性可以在测试计划中引用,但是不能作为特定线程的变量值 JMeter变量对于测试线程而言是局部变量,这意味着JMeter变量在不同测试线程中,既可以是完成相同的,也可以是不同的,如果有某个线程更新了变量,那么仅仅是更新了变量在该线程中复制的值.例如,“正

JMeter学习笔记--JMeter前置处理器

前置处理器被用来修改作用域内的采样器 HTML 链接解析器:解析从服务器得到的HTML响应,并从中提取链接和表单,使用perl型的正则表达式来寻求匹配项. HTML URL重写修饰符:使用URL重写来保存会话ID用于替代Cookies的Web应用系统. Session Argument Name:从前一个响应抓起参数名,修改器会从页面中找到该参数,并提取参数值. Path Extension: 一些web应用通过附加一个分好加上会话ID参数来重写URL Do not user equal in

JMeter学习-008-JMeter 后置处理器实例之 - 正则表达式提取器(一)概述及简单实例

上文我们讲述了如何对 HTTP请求 的响应数据进行断言,以判断响应是否符合我们的预期,敬请参阅:JMeter学习-007-JMeter 断言实例之一 - 响应断言 那么我们如何获取 HTTP请求 响应结果中的数据呢?此文以获取类目 手机数码-手机通讯-苹果 结果列表中的第一个商品的系统编号为例演示(脚本基于上篇文章,请知悉). 如下为请求响应数据中的部分数据,我们最终要获取的数据为 "sysNo": "2142717" 中的 2142717. 1 2 3 4 5 6

JMeter学习-015-JMeter 断言之-Bean Shell Assertion

前面的博文中有对 JMeter 中的 响应断言 进行了讲解并实例演示,详情敬请参阅博文:JMeter学习-007-JMeter 断言实例之一 - 响应断言. 在 JMeter 中总计提供了如下几种 BeanShell 组件: Beanshell Sampler:单独的采样器. Beanshell PreProcessor:针对其他采样器的前置处理器.可以在采样器执行之前进行预处理操作,生成相关测试数据供采样器使用,相当于 TestNG 中的 before annotation. Beanshel