文章来源:http://geek.yihaomen.com/article/2.html
本教程是关于JMeter的。我们将会涉及到的要点如下:
我们会解释JMeter是用来干什么的。
JMeter是如何设计和实现的以及涉及到哪些技术。
如何正确的安装和配置它。
它的用户界面(UI)的基本功能。
详细介绍如何配置不同的测试计划。
展示如何分析它的输出结果。
最后我们会提到一些重要的最佳实践。
本文所提到的所有示例的配置和实现环境是: Java 8 update 0.20,Eclipse Luna 4.4, JMeter 2.11 和MySQL Community Server 5.6.21.
1. 简介
JMeter是一个应用程序,它提供了多种功能,使得可以通过不同的技术和协议来配置和执行负载、性能和压力测试。
它能够模拟各种不同类型的请求,来访问各种数据库、FTP、HTTP、HTTPS或者其它类型服务器。
让我们还是先来简要解释一下上面提到的这些概念:
负载测试:这种类型的测试会测试系统或应用程序在承载它们被设计和实现时设定的最大值的极限情况如何响应。这种测试用来衡量在极端条件下系统和应用程序的表现。
性能测试:这些测试用来检查系统在性能方面的表现,也就是,在特定的负载下,系统会如何响应以及它的稳定性。
压力测试:这些测试会采用比系统设计之初更多的数据或资源从而超出各模块的承受值,并试图击溃、压垮系统。
JMeter最初被设计用于测试web应用程序,但是后来它的功能扩展到其它测试领域;现在它能够用来测试几乎任何类型的程序,也可以用于在你的应用中执行功能测试。
JMeter是Java桌面应用程序,它的UI是使用Java Swing API实现的。基于这两点,JMeter是跨平台的,可以运行在任何安装了Java虚拟机的机器上:Windows、Linux、Mac。
其框架能够支持多个线程和线程组的并发操作执行,这在配置压力和负载测试时会非常有用。它非常易于扩展,并有大量可用的插件。
JMeter是Apache软件基金会的成员,并且是完全免费和开源的(http://www.apache.org/licenses/)。
本文主要针对那些对JMeter没有任何了解的开发人员和软件工程师,可以作为他们学习使用JMeter的入门教程。
本文还提供了一些示例来演示不同场景下如何配置和运行测试计划。在接下来的章节中,我们会了解到如何安装JMeter、如何配置、运行、存储和分析不同类型测试计划的结果。
安装和运行JMeter,请遵循以下步骤:
首先,你必须安装Java环境。你需要安装JRE1.6及以上的版本。具体安装步骤,只需到Oracle下载页面安装和你系统对应的安装包即可:http://www.oracle.com/technetwork/java/javase/downloads/index.html.
设置环境变量JAVA_HOME指向你的Java安装目录的根目录。Windows下设置如:
JAVA_HOME=C:Program FilesJavajdk1.8.0_20
|
或者你安装的任何Java版本。
添加Java的编译路径到系统路径(System Path). Windows下的设置,添加如下:
C:Program FilesJavajdk1.7.0_25bin
|
到系统环境变量Path的最后。
检查确认Java已经安装正确,可以在命令行输入命令:
java -version
|
应该可以看到类似如下输出:
java version
"1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
|
最新版本JMeter下载地址:http://jmeter.apache.org/download_jmeter.cgi
解压JMeter到目录 C:>JMeter
for example (Windows下路径).
JMeter的目录结构大致如下所示:
apache-jmeter-2.9
apache-jmeter-2.9bin
apache-jmeter-2.9docs
apache-jmeter-2.9extras
apache-jmeter-2.9lib
apache-jmeter-2.9libext
apache-jmeter-2.9libjunit
apache-jmeter-2.9printable_docs
|
启动JMeter,以Windows为例,进入目录 C:jmeterapache-jmeter-2.11bin
运行 jmeter.bat
.
你应该会看到类似下图的JMeter GUI的启动界面:
JMeter GUI非常的直观、易于使用;常见的文件操作菜单如新建、打开、保存、另存为等,一些特定的菜单如启动/停止测试计划和进入配置项。每个测试计划、线程组和测试计划节点(后面的章节会详细讲解)在单击右键时都会显示不同的上下文菜单选项。
JMeter也提供了很多的本地化语言,可以很方便的更改UI的显示语言。
正如我们前面提到过的,GUI非常直观、易于使用,为每一个菜单和按钮提供了通俗易懂的提示信息。JMeter如此的广泛使用,除了它本身的高质量之外,这种易用性也是很重要的一个原因,理解并学习其使用方法确实是非常的简单。
JMeter可以支持几乎任何类型系统的测试,但是一般而言,以下几种协议是开箱支持的:
Functional test using JUnit and Java applications.
Web:HTTP, HTTPS网站 ‘web 1.0′ web 2.0 (ajax, flex 和flex-ws-amf:我们在后面的章节会介绍如何测试一个潜在的网页以及它的响应。
Web Services: SOAP / XML-RPC.
通过JDBC驱动程序驱动的数据库测试。JMeter支持几乎所有的数据库类型,你只需要准备一个合适的驱动程序、将它放在JMeter安装目录的相应目录下。本文接下来的示例中我们使用MySQL。
目录服务: LDAP.
通过JMS测试面向消息的服务
基于POP3, IMAP, SMTP的邮件服务.
FTP 服务.
基于JUnit和Java应用的功能测试。
基本来说,JMeter的使用分为以下几部分:创建、配置和执行测试计划,分析其结果。测试计划是一组基于远程服务器(或客户端)、遵循特定指令执行的请求集合。
在一个测试计划的配置中,你可以指定输入参数、输出参数,也可以指定用来判定这个测试计划是否执行成功必须满足的基本条件。
JMeter的测试计划由多个不同组件组成。下面列出一些其中最重要的组件,并附有它们在JMeter UI的配置方法和主要用途:
线程组基本来说是一组不同的测试计划元素的组合。它的‘根’是测试计划,而它是用来控制基本的全局参数设置的。
创建一个测试计划,你需要首先创建一个线程组,然后设置它的线程数、准备时长(ramp-up period)、循环次数和失败时的响应:
线程数(Number of threads):执行测试计划时需要使用的线程数量,这个参数在压力测试和负载测试中非常重要。
准备时长(Ramp-up period):JMeter用来启动所有线程的耗时。
循环次数(Loop count):迭代次数,即该测试需要被执行的总次数。
失败时的响应(Error behavior):出错的情况下如何响应:停止当前线程,停止整个测试,继续……
线程组也有开始和结束时间的设置项。选中“调度器”的复选框,会出现一个包含调度器参数的面板,在其中可以设置开始和结束时间。
这些设置完成后,你可以开始在线程组中加入一些其它测试计划元素,如取样器、监听器和定时器。我们会在接下来的章节解释这些概念。
取样器用来发送请求到不同类型的服务器。它们是测试计划的基本元素,所有的其它工作都围绕它们展开:执行请求(基于已保存的设置),这些请求会产生一个或多个响应结果以供后面的组件分析。
JMeter中可用取样器的列表如下(本教程中会提到其中部分内容):
访问日志取样器
AJP取样器
Bean shell取样器
BSF取样器
调试取样器
FTP取样器
HTTP取样器
Java取样器
JDBC取样器
JMS取样器
JSR223取样器
JUnit取样器
LDAP取样器
邮件阅读器取样器
MongoDB取样器
OS进程取样器
SMTP取样器
SOAP
TCP取样器
测试操作
从上面的列表我们可以看到,有很多不同类型的取样器;这个列表是不完整的,因为还存在很多由不同JMeter插件实现的取样器。每个取样器的配置项取决于它执行的请求,这就意味着,有些取样器具有某些共性的设置,而另一些则因为其请求的性质而具有完全不同的设置。
逻辑控制器用于在线程组内控制不同取样器的执行顺序。JMeter中所有可用的逻辑控制器如下:
简单控制器
循环控制器
单次执行控制器
交替控制器
随机控制器
随机顺序控制器
吞吐量控制器
运行时控制器
If控制器
While控制器
Switch控制器
ForEach控制器
模块控制器
包含(Include)控制器
事务控制器
录制控制器
监听器提供了多种方法来查看取样器中的请求所产生的结果。监听器可以转换结果并输出为表格、结果树或纯文本日志文件。
可以在测试计划的任意位置添加监听器,但是它们只能从取样器中收集和它们本身对应或以下级别的数据并解析。
JMeter中可用监听器如下:
取样结果保存配置
整体图形结果
图形结果
花键可视化(Spline Visualizer)
断言结果
查看结果树
聚合报告
用表格查看结果
简单数据写入器
监视器结果
分布图(阿尔法)
聚合图形
邮件观察仪
BeanShell监听器
概要报告
定时器用来定义请求之间的延迟间隔。如果不指定的话,JMeter会在当前请求执行完毕后,立即执行下一个请求,而没有任何等待时间。
JMeter中的可用定时器:
固定定时器
高斯随机定时器
统一随机定时器
固定吞吐量定时器
同步定时器
JSR223定时器
BeanShell定时器
BSF定时器
泊松(Poisson)随机定时器
断言用来判断取样器请求响应的结果是否如用户所期望,是否正确。基本上,断言类似于单元测试中的断言,用来校验被测试应用的响应结果。你可以为每个测试计划单独设定哪种断言起作用。
JMeter中的可用断言如下:
Bean Shell 断言
BSF 断言
比较断言
JSR223断言
响应结果断言
持续时间断言
大小(size)断言
XML断言
MD5Hex Assertion
HTML断言
XPath断言
XML模式断言
你可以使用配置元素向取样器请求传递不同的参数。使用配置元件,可以定义变量(动态改变的),后面的取样器都可以使用它们。它们的执行开始时间是在所属节点的最开始,早于取样器执行,所以取样器可以正确的使用这些变量。
JMeter中可用配置元件如下:
计数器
CSV数据集配置
FTP请求缺省值
HTTP授权管理器
HTTP缓存管理器
HTTP Cookie管理器
HTTP代理管理器
HTTP请求缺省值
HTTP信息头管理器
Java请求缺省值
Keystore配置库
JDBC连接配置
登录配置元件/素
LDAP请求缺省值
LDAP扩展请求缺省值
TCP取样器配置
用户自定义变量
简单配置元件
随机变量
前置处理器是先于取样器执行的一些元素(或者说动作、断言或其它任何基本的东西)。它们可以从响应中提取变量,以供后面执行的取样器使用。
前置处理器中可以使用的元素如下:
HTML链接解析器
HTTP URL 重写修饰符
HTTP用户参数修饰符
用户参数
JDBC前置处理器
JSR223 前置处理器
RegEx用户参数
BeanShell 前置处理器
BSF 前置处理器
后置处理器是取样器执行完毕后执行的一些元素。它可以用来处理响应数据并提取结果值以供后面的其它组件使用。
后置处理器中的可用元素:
正则表达式提取器
XPath 提取器
结果状态操作句柄
JSR223 后置处理器
JDBC 后置处理器
BSF 后置处理器
CSS/JQuery 提取器
BeanShell 后置处理器
Debug 后置处理器
测试计划中的元素是有序的,并且总是按下列方式执行:
1 – 配置元件
2 – 前置处理器
3 – 定时器
4 – 取样器
5 – 后置处理器(只在有有效结果时执行)
6 – 断言(只在有有效结果时执行)
7 – 监听器(只在有有效结果时执行)
这里要说一个比较好的实践,就是一个测试计划可以包含一个或多个测试计划,另一种常见做法是按照功能或技术上的逻辑关系进行分组。
启动测试计划,只需点击 “运行” 按钮:
如果要启动测试,同时跳过所有的中断,可以点击按钮 "无中断运行"
点击"停止"
按钮来停止测试:
也可以设置禁止某些测试计划运行,只需要在对应的测试计划上右键选择“Disable”:
如上图所见,被禁止执行的测试计划显示为灰色而且不能执行,但是可以修改和重新配置。
本章我们会讲一下怎样创建一个测试计划来通过HTTP测试特定的网页。本例中我会使用网站 http://www.wikipedia.org site.
目前已经说了很多的理论知识,现在让我们来看看如何“实际的”配置一个HTTP请求测试计划。
重命名测试计划为你喜欢的一个名字
在这一步中,会配置一些测试计划的通用设置,这将影响到所有线程的操作,你也可以在这里添加需要使用的外部类库。本例中我们并不会这么做。
添加线程组
在这一步中,你需要创建一个线程组,它负责执行测试的所有组件,并且配置主要参数:线程数,准备时长,和迭代次数。
测试计划的上下文按钮 ->添加 ->线程 ->线程组
你还可以指定在出现错误时需要执行的操作(继续,停止,停止当前线程……)
添加取样器HTTP请求
在这一步我们添加一个取样器,设定相关的我们需要测试的HTTP请求信息:
添加取样器->HTTP请求
对这种类型的请求,我们需要设定不同的参数:
本例中,设置服务器名为我们想要测试的服务器:www.wikipedia.org(不带http或https协议)。如有必要的话,你要相应的修改端口、协议、请求方法等的连接值,本例中我们无需修改这些值。还有一些其他参数用来设置代理、超时和不同的头部请求信息,但是我们在本例只需要使用默认值就可以了。
添加结果监听器
这是一个必需的步骤,以便后面可以看到执行结果;我们在本教程前面章节提到过可以有多种方式来实现,对于本例的HTTP请求测试计划,我们使用查看结果数(View Results Tree):
添加监听器->查看结果树(View Results Tree)
本例中我们不会更改任何配置属性的默认值。
保存测试计划并执行文件-》保存(快捷键“Control+s”)运行-》开始(或直接点击Play按钮)
在监听器中查看结果
可以看到,所有的请求都已经和预期的一样执行完毕,而且返回了有意义的结果,所以看起来我们想要测试的网页工作正常(如果这就是预期的结果)。我们可以概览一下这些结果来看看返回的数据是否正确。
目前为止,我们已经完成了配置测试计划、发送一串请求到指定服务器、解析服务器的响应结果。现在我们来看一看如何使用其它类型的测试组件,例如定时器和断言。
添加定时器
右键单击测试计划,添加一个定时器:
添加定时器->常量定时器
我们设定它延时500毫秒。每一个请求会在上一个请求执行完毕后等待500毫秒。
添加持续时间断言
右键单击测试计划,添加一个持续时间断言;我们设置如下:如果响应时间超过100毫秒,则判断为false。我们这里设置为“只对主取样器有效”。
添加断言->持续时间断言
执行(保存之后)这个测试计划后我们将会看到一些断言错误:
很明显是因为我们只给持续时间断言设置了100毫秒才导致了这种结果;如果我们修改配置为2000毫秒,则几乎所有的请求都能够及时完成。
添加大小断言添加断言->大小断言我们设置断言为响应的长度超过5000字节:
运行测试后我们会看到返回的响应总是大于5000;如果有错误响应返回的话,它的大小可能就会小于5000,这时断言将失败。
现在我们来看一看如何针对MySQL数据库配置、运行和分析测试结果。本例使用MySQL数据库但是也适用于任何其它类型的数据库如Oracle、MongoDB或其它。
安装MySQL
如果你本机没有安装MySQL的话,可以通过http://dev.mysql.com/downloads/下载并安装MySQL服务器,非常简单。
下载MySQL驱动程序
下载mysql 驱动程序 (mysql-connector-java-5.1.6) 并拷贝到JMeter的类库目录 C:jmeterapache-jmeter-2.11lib.
启动MySQL
启动数据库服务器,使之能够接收你发送的查询请求。
创建数据库
你可以按需创建数据库,这里演示一个非常简单的例子:
create database jmeter;
use jmeter;
create table jmeter_stuff(
id
int, name varchar(50), description varchar(50));
insert into jmeter_stuff(
id
, name, description)VALUES(1,
"dani"
,
"the boss"
);
insert into jmeter_stuff(
id
, name, description)VALUES(2,
"topo"
,
"the worker"
);
insert into jmeter_stuff(
id
, name, description)VALUES(3,
"tupac"
,
"the other"
);
|
创建测试计划
像前面的章节一样创建测试计划:创建一个线程组、一个JDBC类型的配置元素、一个JDBC类型的请求取样器;再添加一个监听器用来解析和查看执行结果,就像我们前面例子中做的一样。
唯一的区别是本例中我们使用的取样器是JDBC取样器。
JDBC取样器
为Variable Boundto Pool中的变量起一个有意义的名字,并写入一些SQL语句:
select
* from jmeter_stuff;
|
JDBC 连接配置
在取样器中新增一个JDBC连接配置项。
右键单击JDBC取样器->添加连接配置
修改参数设置如下:
Variable Bound to Pool= same name as
in
the sampler
Database URl=jdbc:mysql:
//localhost
:3306
/jmeter
JDBC Driver class=com.mysql.jdbc.Driver
username=
password=
set
username and password to your MySql credentials.
|
保存测试计划并执行。
通过之前配置的监听器查看结果。
你可以像在HTTP请求测试计划中做的一样,来检查这里的输出结果;你也可以添加一些前置处理器、后置处理器、断言或者其它任何类型你需要的元素。
本例中输出结果是select语句的结果集。
你也可以更改取样器中的SQL语句,来达到更新数据的功能。
下面的截图显示了请求响应结果的基本信息:
本章我们来介绍一下如何结合使用JMeter和JUnit。这能够极大的帮助我们在负载和性能测试中执行功能测试。
首先你要创建一个如下所示的JUnit测试类:
public
class
JMeterTest
{
public
JMeterTest()
{
// just for testing purposes
System.out.println(
"calling the constructor"
);
}
@Before
public
void
setUp()
throws
Exception
{
// just for testing purposes
System.out.println(
"calling setup"
);
}
@After
public
void
tearDown()
throws
Exception
{
// just for testing purposes
System.out.println(
"calling tearDown"
);
}
@Test
public
void
testMe()
{
for
(
int
i =
0
; i <
30
; i++ )
{
// just asserting randomly in order to check what happens in each case
int
randomNumber = (
int
)( Math.random() *
100
);
System.out.println( randomNumber );
assertEquals(
0
, randomNumber %
2
);
}
}
}
|
这个测试类主要包括几个断言以检查JMeter如何使用它们,本教程不对单元测试或者JUnit做详细介绍。
添加测试类到JUnit目录
将单元测试类打包至JAR文件并拷贝到目录 jmeter/lib/junit. 确保这个JAR文件中包含了你想要JMeter执行的那个测试类的.class文件。本文末尾处你可以找到一个带有pom.xml文件的Java项目,你可以直接使用它来生成jar文件并使用到JMeter中。你只需要执行下面的命令来编译代码:
mvn compile
|
你也可以通过Eclipse或你喜欢的其它IDE来导出你的项目为JAR文件,确保其包含字节码和其它生成的文件。
添加JUnit取样器请求
和之前一样我们创建一个测试计划,添加一个JUnit请求类型的取样器:添加取样器->JUnit请求;配置它来执行你之前所创建的测试类中的方法。
在本例中,我们执行的是基于JUnit4的方法,但你也可以选择复选框使得它基于JUnit3执行。
和之前章节一样添加一个监听器来查看结果
运行测试计划
查看结果
下面就是我们刚刚创建的JUnit测试类的执行结果:
我们在上面的截图中可以看到,所有的测试(1个测试,循环10次)都失败了。这是我们的预期结果,因为我们设想这些测试会失败。实际上我们写的这个单元测试并没有任何功能上的意义,可以说是毫无用处的;它只是用来说明如何在JMeter中正确配置并使用这种类型的单元测试。
在使用JMeter来测试应用程序的功能性和业务逻辑时,我们会发现它为我们提供了相当多的便利。本章所介绍的这些概念在测试工作中非常有用,而且它的强大也在于无缝结合了Java语言自身的强项和JMeter的多线程处理能力。
现在我们来解释一下如何配置JMeter来录制HTTP请求。首先需要确保本机安装了Firefox,我本机的是版本32.
设置Firefox使用JMeter代理
进入到Firefox网络设置选项卡,选择手动代理设置项,设置服务器为localhost,端口为8080(具体值取决于你的JMeter设置).然后,选中复选框“所有协议都使用本代理服务器”。
首先我们创建一个测试计划(和之前操作相同)
创建一个新的线程组,取个名字。然后设置这个线程组有50个线程、10秒钟的启动时间和循环次数1.
添加HTTP请求默认值
在刚刚创建的线程组上,添加一个新的配置元素“HTTP请求默认值”。
在这里设置你想要测试的服务器名称。
添加录像控制器
选择工作台,而不是测试计划,添加一个“非测试元素”下的“测试脚本录制器”类型。
现在你应该知道工作台和你的测试计划是分别独立存储的。保存测试计划并不会同时保存工作台。
参照如下配置录制器:
添加定时器
如果你愿意的话可以添加一个(常数)定时器到你的录制器,这样这个定时器在每一个录制的HTTP请求中都可以使用。
开始录制
点击录制器的开始按钮,启动JMeter代理服务器。
显示录像成功
如果你试图访问一个网页来产生一个HTTP请求示例,例如通过Firefox(确保它已经按照前面所讲的配置项配置完毕)访问http://www.oviedin.com ;你就会在测试计划中的录制控制台上看到不同的记录出现。
这些记录实际上都是已经完成的查询之前网页的HTTP请求。只有符合在之前测试脚本录制器中定义的过滤器条件的那些记录才会被存储下来。你可以重新配置它们以供后面的测试计划使用。
JMeter针对高级用户和测试用例有不同的插件,有些需要额外安装,有些是内置支持。
有一些很有用的插件能够使用高级选项转换结果、使用图形化/表格化分析结果,例如http://jmeter-plugins.org/wiki/GraphsGeneratorListener/.
还有一些插件是用来在持续集成工具中连接JMeter、直接在CI软件中运行JMeter测试计划,例如面向Jenkins的“https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin” 。
正如前面提到过的,插件的数量是不断递增的,我们不可能一一列举所有;在你试图实现一个新的插件之前,最好在网络上搜索一下是否已经存在了类似插件。
你可以创建自己的JMeter插件,但这不在本文的讨论范围。
在本文结束之际,让我们记下几个非常有用的技巧和最佳实践:
尽管JMeter UI是一个非常有用和直观的工具、可以方便的配置和创建不同的测试计划,但是那些有经验的用户或许也会想要使用非GUI模式来执行和存储他们的结果。
你可以这么做,输入命令: jmeter -n -t test.jmx -l test.jtl.
假设这个测试就是你想要执行的。你需要提供你的测试存储位置的完整路径。
监听器可以非常方便的解析结果,但他们也占用了大量资源、消耗了大量内存;所以最好能够尽量少的在配置中使用监听器。建议在不再需要这些监听器时,使用标志-l将它们全部删除。
在查看结果树的视图时,选中标志“仅查看错误”,也许你只关心测试过程中发生了什么错误。
在同一个取样器中定义变量和循环,而不是定义多个类似的、仅仅在使用的变量和参数上有细微差别的取样器。
创建JUnit测试计划时,建议提供有意义的错误和断言信息,以使JMeter的输出尽可能的容易理解;这也是我们在做单元测试时也完全适用的准则和建议。
使用Stop(Control+’.’)。这可以尽可能的立即停止所有线程。
使用Shutdown(Control + ‘,’). 这个命令会等待当前工作结束后停止所有线程。其它有用的提示可以查看:https://wiki.apache.org/jmeter/JMeterShortcuts.
这就是本文的全部内容。
我们提到了如何安装JMeter、如何配置它,以及如何执行不同类型的测试,如HTTP请求、面向数据库的测试、面向JUnit的功能测试。JMeter还支持很多其它本文并未提到的测试类型。本教程的目的是提供一个JMeter的概览,并演示如何配置你的第一个测试计划。
我们还介绍了JMeter UI的主要部分,以及如何使用它,还附带介绍了JMeter开箱支持的那些测试计划元素。
最后一章我们提到了如何通过不同的插件扩展JMeter的功能;这个功能对于有经验的用户会非常有用,可以帮助他们实现更高级的需求。