什么是JMeter
Apache JMeter是一个开源的
Java桌面软件。设计的目的就是进行C/S架构软件的负载
测试。随着发展,有很多人也用来进行一些静态资源或者动态资源的
性能测试。可以支持的测试对象有:静态文件,Java Servlets, CGI scripts,Java 对象,
数据库,FTP服务器等等。
JMeter的原理就是模拟产生一个大数据压力包,然后使用不同的负载测试方法去研究
server,object或者network的健壮性以及分析在过载情况下的性能指标。
当然,对于一些简单的workflow,你也可以使用JMeter来建立一套带断言的脚本来进行复杂度较低的回归测试。
有一点要注意的是,JMeter本身不是一个Browser,一定要理解这一点。
一些技术细节我们就不在这里讨论了,下载后就可以很简单的通过bat文件将其运行起来,至于安装java环境,那就不在详细讨论了。
下面,先来理解一些标准术语,方便我们后面进行讲解。
Test Plan
Test Plan,是用来集合需要执行的步骤的一个节点,基本上所有的操作,都是在Test plan里存在的。在Test plan之外的步骤,不会被执行。
你可以将Test plan理解为一个要实现的
测试用例,一个包好了若干测试用例的user story,或者是一个特殊的测试scenario,甚至可以当作一个test suite。完全取决于你在这个Test plan中包含了什么。
包含在Test plan中的节点,我们称之为element。所有的Elements组成了不同结构的Tree存在于Test plan这个root之下。
你可以在其中任意的添加或者删除element或者一个elements tree。
Element
让我们来看看,有哪些element可以被使用。
ThreadGroup
对于每个Test Plan来说,第一个节点永远是ThreadGroup。所有的Controller 元素
和Sampler 元素必须位于ThreadGroup元素中。
ThreadGroup最重要的作用是用来配置一下三个参数:
•
Thread的数量
•
Thread的ramp-up时间
•
执行该Test Plan的次数。
Thread的数量我们很好理解,就是每一个线程模拟一个用户,执行该test plan所有的步骤。数量代表用户模拟数。但是,有一点要注意,从单server上发起的多用户模拟和多server上发起的多用户模拟需要在客户端进行处理。有些server会把单server上所有的请求当作一个用户的请求,而且无法实现多用户并发的模拟。
Ramp-up period是一个需要仔细考虑的设置。它的含义是在指定的period内把所有的Thread创建完毕。例如,有100个Thread,这个period设置为0,那么就是瞬间并发100个Thread。如果设置为2秒,那么就是在两秒内依次把所有的Thread产生。理论上是每隔2/100=0.02秒一个请求。
所以,如果我们在模拟真实的用户请求是,你要有一个预先的response极限,比如0.01秒/response是极限的话,过低的时间频段,只会带来大量无效的请求,更适合over load情况下的性能测试,而不是需要逐级加压的load test的要求。
另外有一个Think Time也值得关注,Think Time是指的思考时间,是一个很明确的时间间隔,Ramp-up period的时间间隔只是理论上的,而Think Time是指定的时间间隔。在模拟多用户并发操作时,我们还要考虑在不同时间节点上的负载平衡。通过将Think Time 和 Ramp-up period相结合,才能更加贴近真实的用户负载场景。
Controllers
JMeter实际上包含了两种Controller元素:Sampler元素和Logic Controller元素。通过二者的组合,从而实现具体的测试内容。
Sampler元素用来定义哪些请求要被发送到server。而且Logic Controller元素则控制那个Sampler元素在什么时候被发送。
Sampler
JMeter现有的Sampler元素有:
•
FTP请求
•
HTTP请求
•
JDBC请求
•
Java Object请求
•
LDAP请求
•
SOAP/XML-RPC请求
•
Web Service(SOAP)请求
每个元素里面都有一些相关的属性需要配置来完成请求发送的任务。同时为了更好的控制业务层次,还提供了很多Configure元素来提供给这些Sampler元素进行调用,从而更加完善的控制流程。
同时可以给Sampler元素配置上一个Listener元素用来记录请求返回的结果。当你想对这些返回的结果进行一个验证是,再添加一个Assertion元素即可。
Logic Controllers
对于逻辑控制,那是必不可少的,可以将我们单一的线性步骤列表,变成一个可控制的多层次的复用模块的组合。
提供可以使用的Logic Controller元素有:
•
Simple Controller 用于组合sampler和其他logic Controller
•
Loop Controller 用于控制loop循环
•
Once Only Controller 用于控制仅一次的操作,例如login
•
Interleave Controller 交错控制,使得包含的步骤交错执行在每个循环中。
•
Random Controller 随机控制,随机选择包含的步骤之一进行执行
•
Random Order Controller 随机顺序控制,以随机的顺序执行所有的步骤
•
Throughput Controller 执行频度控制,用于控制执行步骤的范围和量。
•
Runtime Controller 生命周期控制器,用于控制可生存的时间长度
•
If Controller 控制if操作
•
While Controller 控制while操作
•
Switch Controller 控制switch操作
•
ForEach Controller 遍历操作控制,用来便利当前元素的所有可执行场景
•
Module Controller 用于控制封装好的Module元素
•
Include Controller 用于引入外部的jmx文件,从而控制多个Test Plan组合。
•
Transaction Controller 控制如何产生额外的时间测量sampler。
•
Recording Controller 控制录制使用的代理服务器的地址
我们会在后面详细的介绍每个controller的具体使用方法。
Test Fragments
该元素是一个特殊的Controller元素,是后来引入的。特点是可以和ThreadGroup处于并列级别的存在于Test Plan的树中。而一般的Controller元素都要位于ThreadGroup的节点之内。
只有当其被Module Controller元素或者Include Controller元素引用后,才会被执行。
Listeners
Listener元素用于提供Jmeter在运行中产生的信息。产生的这些信息,其实就是我们需要的数据报告。也就是我们测试要获得的结果报告。
Listener元素可以产生数据文件报告,图形报告,也可以是直接存储为各种文件格式的报告。
Timers
JMeter在ThreadGroup中产生的Thread都是没有任何停顿的,哪怕是设置了产生间隔,也仍然是连续的去产生Thread,每个Thread之间没有任何停顿。如果你想要在每个Thread间进行停顿,需要设置Timer元素。当然,Timer主要还是用于Sampler去控制产生的压力,从而避免过压的产生,从而得不到有效的数据。
Assertions
当你需要对server返回的数据进行一些分析和判断是,需要使用的就是Assertion元素。这在大压力的情况下很有必要,因为有可能返回速度达到了你的要求,但是很多系统在无法response时,也会返回一条回应。通过Assertion元素,我们才能清楚的知道成功率是多少。
当然,如果你是来构建一套回归测试suites,那么Assertion元素是必不可少的。
Configuration Elements
Configuration element是为Sampler元素服务的。他们不会直接的参与请求的发送过程,但是发送的内容是通过Configuration 元素和Sampler元素的内容组合而成的。该元素只能被同一个父节点的兄弟节点以及子节点所使用,父节点的兄弟节点无法使用。
Pre-Processor Elements
该元素主要是在Sampler元素发送请求之前,进行一些预处理操作使用。
Post-Processor Elements
该元素主要是在Sampler元素发送请求之后,进行一些收尾处理操作使用。最常用的实例就是在获得response的data时候,从data中提取我们想要的特定数据。
Common Execution Order
对于所有element的执行顺序,一般来说是这样的:
Configuration element
Pre-Processor
Timer
Sampler
Post——Porcessor
Assertion
Listener
(我以为listener会在Assertion前面呢)
Properties and Variables
JMeter的properties在文件jmeter.properties中定义。 对于JMeter来说,这是全局共享数据。主要是用来定义一些常用的默认值。在Test Plan中,可以覆盖一些默认的properties。
而JMeter的variables是服务于每个Thread的局部变量。每个Thread使用的variables都是不同的,完全取决它们的自己需要。
而且需要注意的是,Thread在执行的时候是复制了一份variables的副本,修改也是基于副本修改,不会影响被多个Thread共享的原本。
而且variables支持正则表达式。
对于在Test Plan和User Define Variables Configuration Element中定义的variables,是可以被包含在该Test Plan中的所有步骤共享。并且可以使用Set方法去设置新的值,从而使所有的步骤都获得更新。
使用variables最大好处就是可以数据参数化。Variables本身是作为一个储存一个可被共享的常量来设计的。但是,它的本质还是一个可变的数据引用对象。
对于一个循环中,或者多个Test Plan中的一个Test Plan,实际上它等同于一个常量。但是,当多个循环和多个Test Plan存在时,我们要操作的数据对象是相同的,但是数据对象的值可以根据场景进行变化,这就为什么要对将那些最常用的数据对象进行参数化。
举个简单的例子帮助你更好的理解:
比如我们要循环访问一个站点的不同页面, 去查看一个特定的字符串是否存在。那么我们可以将站点地址参数化,从而在不同的站点的Test Plan中使用同一个variable,只需要修改它的值即可。同时,我们在每个page中check的特定字符可以是相同的,也可以根据不同的页面不同。那么将这个特殊字符参数化以后,我们可以用相同的Module来执行所有的重复操作