为什么选择使用JMeter

当被问到这个问题的时候,也许你会在脑海里产生很多的理由,比如:

  • Apache基金会下的开源项目,没有版权问题;
  • 为数不多的还在持续更新的开源性能自动化测试工具;
  • 支持协议丰富,是商用测试工具最佳替代品;
  • 有专门的插件项目做支撑,使得你在实践中有更多的选择,比如http://jmeter-plugins.org/就提供了很多优秀的插件为你在使用JMeter执行测试时,可以选择更多的组件来制定测试计划,完成测试过程,监控测试数据。

而我的回答是:

关键在于不要简单地把JMeter理解为一个单纯的性能测试工具,而应该意识到它还是一个优秀的框架,这甚至成为我选择它的一个最根本理由,在这里所有的组件都可以通过自由编写插件的方式进行添加和完善,对于一个测试工程师来说为JMeter编写插件式组件其乐无穷!

JMeter基本组件类型及实现方法

对于JMeter的基本组件,我们可以将其简单的划分为两大类:

  • 一类是具备GUI的组件,即可以通过JMeter图形管理控制器在测试计划Tree中进行添加的组件,主要包括ThreadGroup(线程组)、Config(配置元件)、Timer(定时器)、Modifier(前置处理器)、Extractor(后置处理器)、Controller(逻辑控制器)、Sampler(测试抽样器)、Assertion(断言)和Listener(监听器);
  • 另一类是非GUI组件,这类组件典型的代表是Function(函数)和某些子测试抽样器,如JavaSamplerClient。

对于组件一般有两种实现方法:

  1. GUI与逻辑控制分离:GUI部分通过继承各种组件GUI抽象类,逻辑控制部分通过继承组件逻辑抽象类和实现各种接口方式从而实现不同组件的内部逻辑控制;
  2. GUI与逻辑控制不分离:与分离方法的区别在于不单独实现GUI部分,在逻辑控制部分通过实现TestBean接口方法从而实现对GUI界面的配置。

JMeter插件式组件实现细节概述

TestElement是所有组件的最基本单元,组件类都是TestElement类的子类,JMeter定义了上一章节所介绍的几种组件模型,并对其规范了各自所需发挥的作用。

(1)GUI部分的实现 
GUI部分的实现我们可以在JMeter实现主类org.apache.jmeter.JMeter中发现端倪,该类实际实现了JMeterPlugin接口中的getIconMappings()方法来映射组件所对应的GUI图标,并为映射关系定义了一个二维数组,如下代码:

private static final String[][] DEFAULT_ICONS = {
{ "org.apache.jmeter.control.gui.TestPlanGui", "org/apache/jmeter/images/beaker.gif" },
{ "org.apache.jmeter.timers.gui.AbstractTimerGui", "org/apache/jmeter/images/timer.gif" },
{ "org.apache.jmeter.threads.gui.ThreadGroupGui", "org/apache/jmeter/images/thread.gif" },
{ "org.apache.jmeter.visualizers.gui.AbstractListenerGui", "org/apache/jmeter/images/meter.png" },
{ "org.apache.jmeter.config.gui.AbstractConfigGui", "org/apache/jmeter/images/testtubes.png" },
{ "org.apache.jmeter.processor.gui.AbstractPreProcessorGui", "org/apache/jmeter/images/leafnode.gif"},
{ "org.apache.jmeter.processor.gui.AbstractPostProcessorGui", "org/apache/jmeter/images/leafnodeflip.gif"},
{ "org.apache.jmeter.control.gui.AbstractControllerGui", "org/apache/jmeter/images/knob.gif" },
{ "org.apache.jmeter.control.gui.WorkBenchGui", "org/apache/jmeter/images/clipboard.gif" },
{ "org.apache.jmeter.samplers.gui.AbstractSamplerGui", "org/apache/jmeter/images/pipet.png" },
{ "org.apache.jmeter.assertions.gui.AbstractAssertionGui", "org/apache/jmeter/images/question.gif"}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到只要是插件类的GUI部分继承了以上数组中的GUI类,JMeter框架便会自动将其映射为所对应的组件类型和图标。

(2)逻辑控制部分的实现细节,我们根据组件类别进行一一介绍:

ThreadGroup(线程组)组件

ThreadGroup(线程组)组件继承AbstractThreadGroup抽象类,通过重写各类控制方法,如void scheduleThread(JMeterThread thread) 、stopThread(String threadName, boolean now) 、threadFinished(JMeterThread thread)等,来达到控制和协调各线程(虚拟用户)的行为,线程组是构建一个性能测试模型的最基本组件。


Config(配置元件)组件

Config(配置元件)组件相对其他组件比较特殊,通过继承ConfigTestElement类或只需要GUI部分的实现即可完成本体任务,而对于一个需要配置的组件类则需要实现ConfigMergabilityIndicator接口的public boolean applies(ConfigTestElement configElement)方法,用来指明哪些Config组件可以用来对其进行配置,这里参考TCPSampler的源代码如下:

private static final Set<String> APPLIABLE_CONFIG_CLASSES = new HashSet<String>(
Arrays.asList(new String[]{
"org.apache.jmeter.config.gui.LoginConfigGui",
"org.apache.jmeter.protocol.tcp.config.gui.TCPConfigGui",
"org.apache.jmeter.config.gui.SimpleConfigGui"})); @Override
public boolean applies(ConfigTestElement configElement) {
String guiClass = configElement.getProperty(TestElement.GUI_CLASS).getStringValue();
return APPLIABLE_CONFIG_CLASSES.contains(guiClass);
}

以上代码指明LoginConfigGui、SimpleConfigGui和TCPConfigGui这三个配置元件可以对TCPSampler组件进行配置。


Timer(定时器)组件

Timer(定时器)组件通过继承AbstractTestElement抽象类,实现Timer接口的delay()方法来实现对时间的控制,主要的控制内容如下:

  • 控制线程延时,即用来模仿思考时间(ThinkTime)或键盘时间(KeyTime);
  • 控制线程行为,如SyncTimer(同步计时器),就是内部利用CyclicBarrier来控制阻塞和释放全部运行线程的逻辑行为,从而达到“集合点”的目的。

Modifier(前置处理器)组件

Modifier(前置处理器)组件通过继承AbstractTestElement抽象类,实现PreProcessor接口的process ()方法控制逻辑,常常需要对线程上下文中的当前Sampler和前一个SampleResult进行识别和判断,以做出正确的处理,一般的行为是通过取出SampleResult的某些值或直接在当前Sampler启动sample方法之前对其某些属性进行修饰。


Extractor(后置处理器)组件

Extractor(后置处理器)组件通过继承AbstractTestElement抽象类,实现PostProcessor接口的process ()方法控制逻辑,常常需要对线程上下文中的前一个SampleResult进行识别和判断,以做出正确的处理。


Controller(控制器)组件

Controller(控制器)组件通过继承GenericController类,通过重写Sampler next()、void setDone(boolean done)、int getIterCount()、void reInitialize()等方法来控制Sampler的测试行为。


Sampler(测试抽样器)组件

Sampler(测试抽样器)组件继承AbstractSampler抽象类,通过重写SampleResult sample(Entry e)方法,实现测试过程以及测试结果的采集功能。


Assertion(断言)组件

Assertion(断言)组件通过继承AbstractTestElement抽象类,实现Assertion接口的getResult(SampleResult result)方法对结果内容进行判断,从而实现断言方法,用于对Sampler组件所产生的抽样采集结果内容进行断言。


Listener(监听器)主要有两种方案:

  • 直接继承AbstractTestElement,实现sampleListener或Visualizer等接口方法
  • 实现ResultCollector和Runnable等接口方法

我们可以从实际用途上将其分为两大类Report (报告)和Vizualizers(监视器)。 
Report (报告)继承AbstractListenerElement抽象类,通过实现sampleOccurred(SampleEvent e)方法,对所有采集事件中所产生的SampleResult进行处理,从而生成报告; 
Vizualizers(监视器)主要用于特定的监控任务,比如监控系统资源利用率的组件,与Report的区别在于Vizualizers必须继承一个 ResultCollector类,并在收集器中通过开启额外线程方式完成自定义的数据采集。


上面还介绍了诸如Function(函数)这一类非GUI组件,这类组件的实现比较简单,而且功能比较单一,只需要继承相应的抽象类。

(3)一些TestElement需要实现的主要接口说明

为了实现更多的特性,组件在必要时还需要实现一些主要的接口和方法,下面举例说明:

NoThreadClone接口: 
This class is not cloned per thread, so this is shared,可以理解为一旦实现了NoThreadClone接口,这个TestElement便不会在线程组下的每个线程中创建,而是一个全局化的组件,因此,无法使用getThreadContext()方法。反之,我们可以发现JMeter实际是通过TestElement的clone()方法为线程组下的每个线程拷贝创建属于各自的线程上下文内的TestElement,A new instance is created for each thread group, and the clone() method is then called to create copies for each thread in a thread group.如果想要对某些共享资源进行同步操作,需要参考如下方法:

private transient Object lock = new Object();//锁对象不需要进行序列化,因为分布式在不同主机内存中的锁对象不必保持一致
@Override
public Object clone() {
Clazz clazz = (Clazz) super.clone();
clazz.lock = lock; //保证所有克隆对象共享同一个锁对象
return clazz;
}

注:这是种显式的共享对象方法,由于Java在克隆类对象时,默认是一种“浅克隆”方式,因此,不显式的共享上述锁对象,该锁对象也是默认共享的。

LoopIterationListener接口: 
将通过实现 iterationStart(LoopIterationEvent event)方法,控制对每次发生迭代事件时所需要实现的逻辑。

Serializable接口: 
为了实现在分布式测试模型中保持一些配置和对象的一致性,就需要实现Serializable接口,通过序列化方式保持不同主机对象属性的一致性。

TestStateListener接口: 
将通过实现testStarted(String string)和testEnded(String string)方法,控制对测试状态变化事件时所需要实现的逻辑。

另外,在实际插件的编写过程中还会包括如Remoteable、Interruptible、ThreadListener等接口的应用,会在后面的具体章节进行详细介绍和应用。

组件即插件,只需一步插入JMeter框架

将编写好的插件式组件插入JMeter框架非常简单,只需要将组件整体打包为jar包,并将其拷贝到$JMETER_HOME/ lib/ext路径下即可使用!

Apache Jemeter 开发插件的更多相关文章

  1. 如何为Apache JMeter开发插件(二)—第一个JMeter插件

    文章内容转载于:http://lib.csdn.net/article/softwaretest/25700,并且加上个人一些截图 本篇将开启为JMeter开发插件之旅,我们选择以Function(函 ...

  2. 如何为Apache JMeter开发插件(一)

    本文转载于http://blog.csdn.net/column/details/12925.html,作者:xreztento 作者写的很精华,我打算在此系列操作一遍后,加多点截图,便于更多人更快上 ...

  3. eclipse SE增加Web开发插件

    最近接触了些java项目,之前安装了eclipse SE版本.没有Web开发插件,调试不了Web代码.点击“Window”--“Preference” 左边菜单栏是找不到“Server”项来配置服务器 ...

  4. Visual Studio 2012 Ultimate 上安装 Python 开发插件 PTVS

    1.我的环境 操作系统:32位 Win7 旗舰版 Service Pack 1 VS版本:Microsoft Visual Studio Ultimate 2012 版本 11.0.50727.1 R ...

  5. 通过Nutch扩展点开发插件(添加自定义索引字段到solr)

    爬虫系统:通过Nutch扩展点开发插件(添加自定义索引字段到solr) 准备工作 爬虫环境 -- nutch2.3.1 + solr4.10.3 + hbase0.98 开发环境 -- Eclipse ...

  6. JMeter开发插件——图片验证码识别

    我们在性能测试中总会时不时地遭遇到来自于应用系统的各种阻碍,图片验证码就是一类最常见的束缚,登录或交易时需要按照图片中的内容输入正确的验证信息后,数据才可以提交成功,这使得许多性能测试工具只能望而却步 ...

  7. [原创] 毕设---在myeclipes中安装Hadoop开发插件

    1.安装Hadoop开发插件 hadoop安装包contrib/目录下有个插件hadoop-0.20.2-eclipse-plugin.jar,拷贝到myeclipse根目录下/dropins目录下. ...

  8. Apache Cordova开发环境搭建(二)VS Code

    原文:Apache Cordova开发环境搭建(二)VS Code 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011127019/articl ...

  9. Apache Cordova开发环境搭建(一)-Visual Studio

    原文:Apache Cordova开发环境搭建(一)-Visual Studio 一.使用Visual Studio开发Apache Cordova手机App 1.版本要求,Visual Studio ...

随机推荐

  1. 为什么在大多数OS中都引入”打开“这一文件系统调用?打开的含义是什么?

    当用户要求对一个文件实施多次读/写或者其他操作时,每次都要从检索目录开始.为了避免多次重复检索目录,在大多数OS中都引入了”打开“这一文件系统调用,当用户第一次请求对某文件进行操作时,须先利用open ...

  2. ansible api常用模块与参数

    ###ansibleAPI 常用模块 用于读取yaml,json格式的文件 from ansible.parsing.dataloader import DataLoader #用于管理变量的类,包括 ...

  3. C# Aspose填充excel模板数据,下载

    public Result<object> GetAExcelFieItem(string[] aid, int kind, string contype) { string fileUr ...

  4. EF Code-First数据迁移

    Code-First数据迁移  首先要通过NuGet将EF升级至最新版本. 新建MVC 4项目MvcMigrationDemo 添加数据模型 Person 和 Department,定义如下: usi ...

  5. Spring.Net---3、IoC/DI深入理解

    ------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...

  6. MongoDB 从入门到精通

    1,安装并启动数据库       从官网(www.mongodb.org/downloads)下载一个适合你平台的版本,我的系统是win7 64位的,下载文件也就10几M,将下载的文件解压放到任何目录 ...

  7. 局域网内配置虚拟机的hostname

    一般上我们在局域网内访问,比如宿主机访问虚拟机的时候可以直接使用IP去访问,大多数情况下也都适用.但是对于有的情况,比如像新版的hbase的配置,它默认将localhost作为hbase.master ...

  8. [LeetCode]Delete and Earn题解(动态规划)

    Delete and Earn Given an array nums of integers, you can perform operations on the array. In each op ...

  9. linux ubuntu 安装nginx

    参考原文 在Ubuntu下安装Nginx有以下方法,但是如果想要安装最新版本的就必须下载源码包编译安装. 一.基于APT源安装 sudo apt-get install nginx 安装好的文件位置: ...

  10. 解决Fiddler无法捕获本地HttpWebRequest(C#.net)请求和HttpURLConnection(Java)请求

    方法很简单,就是设置本地代理 C# HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Proxy = new WebPr ...