Jmeter自动化测试我爱编程

JMeter接口自动化测试

2018-05-21  本文已影响143人  __yanyan

1 引言

这估计是目前国内能找到的相对比较全面的JMeter自动化测试介绍了吧。希望能给予您一点帮助。

1.1 JMeter介绍

Apache JMeter是开源软件,它可以用来做负载测试和性能测试。它最初设计是用来测试Web应用程序,但现已扩展到其他测试功能。

Apache JMeter可以用来测试包括基于静态和动态资源程序的性能,例如静态文件,Java Servlets,Java对象,数据库,FTP服务器等等。Jmeter可以模拟一个在服务器、网络或者对象上大的负载来测试或者分析在不同的负载类型下的全面性能。

另外,JMeter能够通过用断言创造测试脚本来验证我们的应用程序是否返回了我们期望的结果,从而帮助我们回归测试我们的程序。为了最大的灵活性,JMeter允许我们使用正则表达式创建断言。

1.2 自动化测试

何谓自动化测试?

一般是指软件测试的自动化,软件测试就是在预设条件下运行系统或者应用程序,评估运行结果,预先应包括正常条件和异常条件。

自动化测试的优缺点:

- 优点:

  1. 节省人力,只要代码维护得好,不需要那么多人就可以完成测试。
  2. 节省时间,测试脚本可以晚上或者周末跑。
  3. 优化资源分配,在运行测试脚本的同时,QA可以做其他事情,比如设计新的测试用例。
  4. 方便回归测试,极大提高了工作效率。
  5. 增加软件的可信度,测试是机器执行的,一定程度上排除了因人工测试所造成的忽略性错误,测试结果更加可信。
  6. 能完成手工不容易控制的测试工作,比如对于大量用户的测试,不可能同时让足够多的测试人员同时进行测试,但是却能通过自动化测试模拟同时有很多用户操作,从而达到测试的目的。

- 缺点

  1. 脚本维护成本高,尤其是版本变动比较大的,对于项目来说是潜在的风险。
  2. 不能在发现新的bug。

1.3 阅读对象

对JMeter有一定的了解,会使用JMeter做接口测试的人。

1.4 定义与名词解释

2 核心元件

本文档主要作为接口自动化测试的入门,讲解接口自动化测试中常用的元件。

本文档不对JMeter安装、环境设置等再做介绍,若对JMeter完全陌生者,请自行学习JMeter的基本使用后再查阅本文档。

2.1 用户定义的变量

假设你有一个场景是这样的,你有很多个接口都要用到同一个参数,并且这个参数它的值不是固定不变的。在没有使用用户定义的变量这个元件时,每一次这个参数改变了值,你都必须到用到它的每一个http请求去修改值,如果此时你有一百个这样的接口,显然这样的修改方式也是一件艰巨的任务。

解决这种情况,『用户定义的变量』这个元件是个不错的选择。他允许你定义一个参数,接口用到它只需要通过EL表达式来获取定义的值,这样一来,当参数的值变化时,你只需要改动一个地方,即可完成这上百个接口的修改。

新建配置元件『用户定义的变量』。


点击添加按钮新增一个变量,输入变量的名称和默认值,我们在使用参数时可以通过定义的名称${parameter}来获取变量的值。如下图所示:

通过EL表达式,我们可以获取定义的值,当然如果你懂Java语言,你也可以通过BeanShell去修改这个值。关于BeanShell的一些介绍,我们会在接下来的章节提到。

另外,除了使用『用户定义的变量』这个元件,其实在『测试计划』中也有一个地方可以定义全局参数。如下图所示:

这两个地方创建的变量,都可以使用${parameter}来获取定义的值。

2.2 CSV Data Set Config

JMeter支持使用外部文件来保存接口测试时所要使用的参数,当我们配置了CSV Data Set Config这个元件后,JMeter会根据我们的配置使用指定的文件中的值作为参数。

下面给出的一个例子:

创建帐号密码的外部存储文件,这里我使用的是.txt文件。

以公司测试环境的审批系统为例,在CommonService-userCode.txt文件里面保存登录名和密码,如下图所示:

线程组配置CSV Data Set Config元件,如下图所示:

接口使用EL表达式获取值,如下图所示:

2.3 正则表达式提取器

JMeter支持使用正则表达式提取返回的响应文,比如你有一个接口是使用了上一个接口返回结果的某一个值作为参数,此时你就可以使用正则表达式提取器提取上一个接口返回的值,作为下一个接口调用的参数值。

JMeter的正则表达式和Perl5非常相似,一个很显著的区别是在Perl5正则表达式中使用//作为分隔符,而JMeter是使用()

选中所要提取返回结果的http请求,添加后置处理器-->正则表达式提取器,如下图所示:

为了便于查询匹配到的结果和相关信息,建议加上Debug PostProcessor这个元件。

添加后我们在察看结果树就可以通过Debug PostProcessor来查看匹配结果。如下图可以看到最终匹配结果是:controlSeq=2017116334

通过正则表达式提取接口返回的值,并设置好引用的名称,我们可以使用EL表达式将提取到的至作为下一个接口的请求参数。如下图所示:

最后,我们可以通过察看结果树查看到请求参数的值。如下图所示:

<font color="#ff0000">接下来,我想详细说明一下模板(Template)这个参数的具体用法。</font>

如果你懂Java代码,这个模板的作用其实就跟Java的Matcher.group(int index)是一样的,那么你可以直接过这一章节。如果你不懂代码,或者对Matcher.group()这个方法也不是很清楚,那么请你接着看,下面我举了大量的例子来解释。

在上面的解释中,我只简单的提到这个模板是用来提取正则表达式匹配到的值,下面我们用具体例子来详细说明一下这个参数的用法。

当我输入正则表达式"controlSeq":"(.+?)",模板设置为$0$,我们到察看结果树视图中查看提取结果。

从上图可以看到,controlSeq="controlSeq":"2017116304",即$0$表示匹配内容的整体部分。

当我将模板设置为$1$,查看提取结果为:controlSeq=2017116334,可以看到$1$表示提取括号中匹配的内容。

当我将模板设置为$2$,查看提取结果为:controlSeq=null,可以看到$2$并没有提取到任何匹配到的内容,所以返回null。

好吧,这个正则表达式给到的提示还是比较少,我试着用另外一个复杂一点的表达式来描述。

正则表达式"controlSeq":"(.+?)","beginDate":((.+?){13}),"approveSeq":"(.+?)",我们就使用这个表达式作为例子。

同样,当我将模板设置为$0$,提取结果为:controlSeq="controlSeq":"2017116334","beginDate":1487591184000,"approveSeq":"4772",这个结论与之前说的是一致的,$0$的确表示提取匹配内容的整体部分,没毛病。

当我将模板设置为$2$时,看看会有什么样的结果,是不是还是 <font color="#ff0000">controlSeq=null</font>。

然而我们发现模板提取结果并不是 <font color="#ff0000">null</font>,而是<font color="#ff0000">1487591184000</font>,结合$0$的结果可以发现$2$提取的是((.+?){13})这个表达式所匹配的内容。

同样,你会发现当你将模板设置为$3$时,提取内容为第二个(.+?)表达式所匹配的内容。而$4$则提取的是最后一个(.+?)所匹配的内容。举了这么多例子,想必你也应该知道是怎么一回事了吧。

最后我们来个总结,下面我画了一个图来描述。

2.4 计数器

计数器这个元件,我暂时没想到什么具体的接口测试会用到,或许在分页查询上会使用到。这里我们以一个简单的例子介绍一下。

新建计数器,如下图所示:

设置启动值为1,每次递增1,最大值为5,引用名称使用count,如下图所示:

请求参数使用${count}来获取对象的值。

设置线程数为5,如下图所示:

执行结果,如下图所示:

如上图结果可以看到,当我们将线程组数设置为5时,参数count从1递增到5。

2.5 逻辑控制器

逻辑控制器可以用来控制Samplers的执行顺序,他包括循环控制器、if控制器、事务控制器等等。如图所示:

下面将详细介绍循环控制器(Loop Controller)的使用。

添加一个循环控制器,选中线程组,右键添加-->逻辑控制器-->循环控制器,如下图所示:

输入循环的次数,如果勾选了永远,将一直循环。如下图输入的循环次数是2。

如下图所示,循环控制器中的『查询办件进度』请求被执行了两次。

当然,你也可以使用${parameter}去获取某一对象的值,你甚至可以使用BeanShell Sampler去动态修改这个值。

2.6 BeanShell

1. 什么是BeanShell

BeanShell是一个小巧免费的JAVA源码解释器,具有对象脚本语言特性,亦可嵌入到JAVA源代码中,能动态执行JAVA源代码并为其扩展了脚本语言的一些特性,像JavaScript和perl那样的弱类型、命令式、闭包函数等等特性。

2. BeanShell在JMeter中的使用

BeanShell是最高级的JMeter内置组件之一。它支持Java语法,并使用诸如宽松类型,命令和方法闭包之类的脚本特性来扩展它。如果你的测试用例不常见,通过JMeter提供的组件来实现变得棘手或者甚至不可能,比如说加密解密。此时,BeanShell能实现你的目标。

JMeter中的BeanShell实例可以访问JMeter的API和加载到JMeter类路径中的任何外部类(被引用的jar包需放到JMeter安装目录/lib/ext文件夹中,并在BeanShell脚本编写中使用"import"引入被使用的类)。

JMeter提供了以下启用BeanShell的组件

以上所有JMeter提供的BeanShell组件都有一个共同点就是支持我们使用Java代码去实现更复杂的功能或者去拓展更多的功能,只不过JMeter把这些组件放在不同的位置,这些"不同的位置"最显著的影响就是一个执行顺序问题。

比如,BeanShell PreProcessor这个组件会在接口调用前被执行。在实际生产中,开发人员常会考虑安全问题,对数据进行加密传输,由后台对加密的数据进行解密。对于这样的接口,如果你的参数是使用明文发送,恐怕你怎么调用都无法得到正确的返回值。BeanShell PreProcessor能帮你解决这类问题。

又如,BeanShell PostProcessor,这个组件的设计是在接口调用后执行。对应上面提到的BeanShell前置处理器,这个组件可以用来对返回的加密数据进行解密。或者你可以做一些日志管理之类的事情。

其他的BeanShell组件可自行类推,这里就不再一一举例子说明。使用BeanShell你可以在运行时改变JMeter变量的值,在线程组之间传递Cookie,在发生故障时停止运行测试等等牛逼的事情。

*3. JMeter内置变量

SampleResult

映射JMeter类org.apache.jmeter.samplers.SampleResult。

示例代码:

import org.apache.jmeter.samplers.SampleResult;

String sampleName = SampleResult.getSampleLabel();

log.info("sampleName==>"+sampleName);

ResponseCode

ResponseCode是一个java.lang.String,表示采样器的响应码,即可以通过该参数动态修改响应码。

示例代码:

if(condition){
    ResponseCode="200";
}else{
    ResponseCode="500";
}

ResponseMessage

ResponseMessage是一个java.lang.String,表示响应消息。

示例代码:

ResponseMessage="Failure";

IsSuccess

IsSuccess是一个反映采样器是否成功的java.lang.Boolean。如果设置为true,则采样器被认为是"通过",否则,则为"失败"。

Label

Label是一个java.lang.String,它是用于表示采样器的标签。它可以获取或设置为通常的字符串,并将作为采样器标签列在测试结果中。

FileName

FileName是一个java.lang.String,它包含一个BeanShell脚本文件名(在BeanShell采样器的"脚本文件"节中输入的)。

ctx

ctx是JMeter内置变量中最强大的变量。它代表org.apache.jmeter.threads.JMeterContext类,实际就是JMeter本身。它提供对采样器、执行结果、变量/属性等的读写。

示例代码:

import org.apache.jmeter.samplers.SampleResult; 
import org.apache.jmeter.threads.JMeterContext;

SampleResult result = ctx.getPreviousResult();

String name = result.getSampleLabel();
String url = result.getUrlAsString();

log.info("result name==>"+name);
log.info("current url==>"+url);

vars

vars是最常用的JMeter变量,它是org.apache.jmeter.threads.JMeterVariables类的实例,提供对当前变量的读写。所有的JMeter变量都是java字符串,如果你需要把一些变量存放到一个JMeter变量中,需要先把它转换成字符串。

示例代码:

import org.apache.jmeter.threads.JMeterVariables;

vars.put("count","3");

vars.remove("count");

props

props是java.util.Properties的实例,与vars作用大致相同,区别的是vars是对变量进行读写操作,而props主要是对属性进行读写操作。

示例代码:

import java.util.Properties;

props.get("START.HMS");

log

log表示org.apache.log.Logger类。

示例代码:

log.info("Hello JMeter");

2.7 JMeter调试

正则表达式调试功能

JMeter提供调试正则表达式的功能。当你不确定正则表达式是否正确时,可以使用RegExp Tester,它为测试程序节省了大量的时间,并使得调试更容易,因此你不需要通过多次运行来检测正则表达式的正确性。

创建一个Http请求,点击运行按钮,回到察看结果树界面。如下图所示,选择响应数据,在Search框可以输入我们要查找的东西,检查是否包含在返回内容中。

从左边下拉列表中选择RegExp Tester,如下图所示:

Regular expression中输入我们要检验的正则表达式后点击Test按钮,下面的面板会根据输入的正则表达式输出最终查找结果。如下图所示:

Sampler调试功能

JMeter的调试功能并不是你想象中像常见IDE那么强大,可以一行一行代码检测。JMeter的调试更多是通过查看最后的输出信息来查找问题所在。

使用DebugSampler和Debug PostProcessor能帮助你定位问题。当运行完毕后,打开『察看结果树』并选择相应的调试采样器,你将看到执行后输出的一系列信息,这些信息能帮助你找出实际问题。

如下图所示,我们可以通过Debug PostProcessor查看到正则表达式匹配的结果:

如果是报错信息,我们同样可以通过点击右上角圈出的图标打开log输出信息,如下图所示我们能查看到报错信息。

其他调试功能

JMeter还有其他方面的调试功能,比如调试CSS/JQuery、调试XPath、调试JMeter元素、远程JMeter调试等等。这里只介绍常用的这两种调试技巧,其他调试功能请自行拓展学习。

资料

上一篇下一篇

猜你喜欢

热点阅读