JMeter主要是一个用于load/stress test的工具。因为它具备一套专门的术语和概念,对于我等不是专门作测试的人员来讲初次使用它时确实有点无从下手的感受。只有搞清楚了它的几个基本概 念,用起来才能作到心中有数。虽然JMeter的用户文档讲得很详细,可是那里毕竟没有结合JMeter全部概念讲一个综合应用的例子(实际测试中的 Test Plan每每须要综合运用不少概念的),不失为一个小小的遗憾。 本文结合一个webapplication测试的例子介绍JMeter的完整概念。javascript
JMeter使用的概念有:Thread,Sampler,LogicController, Config Element(配置元素),Timer,Pre-/Post Processor,Assertions, Listener。css
从总体结构上来说,首先一个测试就是一个Test Plan(测试计划),每个Test Plan能够设定Thread Group,Thread Group下面的树形结构就是下面设置的测试配置信息。html
下面是本实例的一个总体配置:java
(图1)web
一个Thread模拟单个测试用户,例以下面的是ThreadGroup元素中的配置信息,它表示模拟100个用户的访问,ramp-up表示100个用户线程5秒钟以内才能所有启动完成。ajax
(图2)正则表达式
*****Sampler是核心概念:express
要经过http访问web server,免不了须要使用Sampler(对于这里的Web测试是HttpRequest Sampler)。所谓Sampler就是对Server的访问,至关于浏览器(可是不解析html/css和javascript),每一次访问请求得 到的响应在JMeter中做为一个Sample保存并经过Listener让用户察看HTTP response的结果和统计图表。因此Sampler是JMeter的核心概念。其余的概念都是围绕着Sampler服务的,好比Pre- processor(预处理器)能够在Sampler向Server发送请求以前定义一些变量或作处理(好比本例图1中的User Parameters);而Post-Processor能够在获得Response以后做一些操做(好比本例图1中的“RegEx extractor - tableuseid”)。图1中包括的Sampler有四个:编程
1) Login.action(在Once Only Controller下面)json
2) Main.action (位于Simple Controller下面)
3) Click Table(afterSelectTable_ajax.action) (位于SimpleController下面)
4) CreateOrder(doOpenGuestTable_ajax.action) (位于SimpleController下面)
下面围绕着以上四个samplers介绍JMeter的其余概念。
*****如何设置多个HTTP Requests的缺省值:
首先在测试一个web application的时候,每一个Sampler都须要设定web server的主机IP地址等信息,而这些信息在每一个Sampler中是相同的,所以能够经过一个Config Element—Http Request Defaults将这些共同信息(好比Web Server主机IP)提取出来保存,而后在上面四个Samplers中就不须要再设置了。
(图3)
*****Once Only Controller:
Login.action是web程序的login功能,每个用户(Thread)都须要单独login,可是在一个 用户的全部HTTP requests中(即一个session)只须要login一次。所以若是能够将这个Sampler放到Once Only Controller下面,保证login只在一个session中执行一次。Once Only Controller是JMeter中的另外一个概念--Logic Controller。Logic Controller相似于编程语言中的for循环那样的控制结构,它能够控制树形结构下面包含的Samplers的执行方式。经常使用的Logic Controller有Simple Controller(就是一个简单的容器,将树形结构下面的Samplers放到一块儿,见图1), 这里的Once Only Controller,还有Interleave Controller(上一次执行下面的一个某个Sampler A,下一次执行下面的一个某个Sampler B)等。
下图是Login.action这个Sampler的设置:
(图4)
*****Sampler中每个用户能够有不一样的URL参数值:
从上图中能够看到在调用login.action的URL参数中使用了一个参数funcType,它的值是从另一个变量${FUNCTYPE}中 读取的。那么FUNCTYPE变量在那里定义的呢?答案是User Parameters中定义了该变量。前面说过,User Parameters是一个Pre-processor,只在Sampler执行以前使用该元素,因此在执行Login.action以前,其中一个变量 FUNCTYPE能够从User Parameters中设置。在本例中,咱们模拟了100个用户,但愿每个用户能够从funcType的两个值{1,2}中依次选一个,所以User Parameters的做用就是在每一个Sampler执行以前,给它设置一个funcType值,每个funcType变量能够设定多个用户,好比本例 中设置了user1和user2,可是实际上测试用户数是100,这种状况下就轮流从user1和user2中选取(好比用户3使用user1的值,用户 4使用user2的值,用户5使用user1的值)。
下图是本例中UserParameters的设置:
(图5)
*****Cookie管理:
几乎全部的Web Application都须要cookie管理,JMeter能够模拟浏览器的作法管理cookie,只须要添加一个Config Element – HTTP Cookie Manager(如上图所示)。
*****如何定义变量:
另外在Simpler Controller下面有一个UserDefined Variables,它也是一个Config Element。在本例中,因为其中一个Sampler “ClickTable(afterSelectTable_ajax.action)”须要一个参数tableId做为输入,可是又不但愿把这个参数值 hard code进去,所以设置一个用户定义的变量TABLEID(注意图中变量的做用域是Simpler Controller下的三个Samplers,可是只有Main.action中用到该变量):
(图6)
*****如何在Http Request Sampler中使用变量:
而后在Sampler “Click Table(afterSelectTable_ajax.action)”中能够按${TABLEID}的方式引用这个变量:
(图7)
*****Regular Expression Extractor提取Http Response信息并保存成变量:
除了上面使用User Defined Variables的方法定义变量以外,本例中仍是用了Regular Expression Extractor从HTTP response的输出结果中获取一个字符串做为一个变量。Regular Expression Extractor是JMeter中的另外一个概念—Post-processor,它的做用是获得HTTP响应后,对结果(好比一个html标签页面的内 容或json输出数据等)进行处理,经过regular expression抽取字符值,存成一个变量给后面的Sampler使用。
例如在Click Table(afterSelectTable_ajax.action)这个Sampler执行完一次HTTP Request以后获得以下的HTTP Response(一个json格式的输出):
{"free":false,"hasError":false,"singleEntry":true,"table_nr":"05","tableid":5,"tableuseid":130}
如今要获得tableuseid的值130,能够用这样一个regular expression:
^.+?"tableuseid":([^} ,]+).*$
上面括号中的内容就是提取130的值,用括号的做用是能够把该值做为一个组,并存成一个变量以便在下一个Sampler--CreateOrder(doOpenGuestTable_ajax.action)中使用。
注:能够用下面的perl命令行交互式测试正则表达式:
perl -n -e '/^.+?"tableuseid":([^} ,]+).*$/ && print "$1\n"'
(图8)
*****在另外一个Sampler中使用RegEx提取的变量:
按照上图的设置,在CreateOrder(doOpenGuestTable_ajax.action)中如何引用该变量呢?根据JMeter的用户参考文档,应该是${tableuse_g1}。
下图是该变量在Sampler--CreateOrder(doOpenGuestTable_ajax.action)中的使用。
(图9)
*****JMeter的函数:
在上图中,还有一个URL参数nocache,它使用一个函数${__time}获取client中的当前时间。
*****Timer:
在上图的Sampler--CreateOrder(doOpenGuestTable_ajax.action)下面 有一个constant timer--delay executing CreateOrder,它的做用是在执行完上一个Sampler(这里的Click Table)以后,延时一个时间段,这样不至于给服务器形成过多的影响。
*****HTTP Response的html内容校验:
在CreateOrder(doOpenGuestTable_ajax.action)的HTTP响应(一个html标签页面的内容)中,咱们需 要检测是否包含一个单词“Beer”,若是没有这个单词,说明HTTP响应出错。这就是自动化的功能测试的思想。可使用JMeter的另一个概念— Assertion完成这项工做,本例中使用ResponseAssertion,以下图所示:
(图10)
*****测试结果的显示:
测试结果能够输出每个Sample的HTTP Request/Response的内容,也能够用图表统计全部的Samples,并保存到文件中。在JMeter中使用Listener这个概 念,Listener的做用就在每一个Sample执行以后根据设置作相应的统计处理。本例中使用到的Listener有两个:View Results Tree和Graph Results。
参考图1(为方便起见,从新贴在下面),总结一下本例Test Plan中用的元素和它们在JMeter中的概念对应关系:
1. Thread: 模拟一个用户
2. Sampler:
1) Login.action(在Once Only Controller下面)
2) Main.action (位于Simple Controller下面)
3) Click Table(afterSelectTable_ajax.action) (位于SimpleController下面)
4) CreateOrder(doOpenGuestTable_ajax.action) (位于SimpleController下面)
3. Logic Controller:Once Only Controller和SimpleController
4. Config Element: HTTP Request Defaults, HTTP Cookie Manager和User DefinedVariables
5. Timer: delay executing CreateOrder
6. Pre-Processor:User Parameters
7. Post-Processor:RegEx extractor - tableuseid
8. Assertions: Response Assertion
9. Listener: View Results Tree和Graph Results
总结:以上介绍的是JMeter的核心概念,JMeter还有不少其余功能,好比分布式测试(在一台机器上测试受单机的性能限制,每每压力测试结果 不能反映真实状况),无图形界面(non-GUID)的测试等等。可是掌握了这些核心的概念,已经能够自如地应对普通的测试方案了。