apache jmeter是apache软件基金会出品的一款用于接口测试,压力测试的开源软件,由于其免费开源,插件j自由扩展,跨平台,所以理论上可以支持所有种类的接口测试。jmeter自身也已经提供了许多优秀的插件,极大地增强了jmeter的能力。
问题引入
jmeter提供了两种运行模式,一种是GUI模式,一种是CLI模式,这两种运行模式有各自的场景:
GUI-图形用户界面:
顾名思义,用户可以在任意支持java的操作系统上打开一个jmeter客户端,因为GUI模式下提供了可视化的脚本编排工具,因此常用于脚本编排。
CLI:
命令行模式,也叫non-GUI,headless(无头模式),可以在不启动jmeter图形客户端的情况下发起脚本测试,CLI模式是更常用的jmeter运行模式,因为不需要启动图形客户端,所以该模式下占用的资源会更少,是在负载测试和压力测试中最常用的运行模式。
无论使用jmeter执行何种类型的测试,都离不开脚本的编排,GUI模式下固然可以编排脚本,但是这种方式在面对现在越来越盛行的敏捷开发及devops理念时稍微显得心有余而力不足,主要的问题在以下几个方面:
碎片化严重:当新的需求完成或旧的需求发生变更时,需要重新编排测试脚本,脚本很难管理或碎片化非常严重。
历史记录难以回溯:每次使用jmeter进行性能测试都会生成新的日志、报告,使用本地文件系统管理这些数据可行,但是想要回溯脚本的整个执行历史基本上是不可能的。
沟通成本高:针对每一个开发需求的测试及缺陷的管理被强制性隔离,测试人员与开发人员的沟通成本极高,这与敏捷及devops的理念是不符的。
质量管控:产品或项目在发版前的质量控制靠测试人员人工控制,当面对大型的项目中成百上千个测试用例时,靠人工控制产品或项目的质量,困难重重。
没有针对不同管理人员的报告:测试人员关心用例的成功率、开发经理关心缺陷趋势、开发者关心缺陷产生的原因、项目经理关心测试覆盖率……,这些都需要有一套平台集中管理测试数据才能实现。
基于以上的问题,想要集中管理jmeter脚本相关的测试数据,首先要解决的一大问题就是:脱离jmeter GUI模式,在自己的测试平台上实现在线编排测试脚本,这将会涉及到jmeter的二次开发。
从目前apache官方放出来的资料来看,只有全部的源代码、客户端使用手册,就连接口文档都是残缺不全的,再加上jmeter自身作为一个平台,第三方可以通过插件扩展的方式对jmeter进行增强,因此二次开发的难度很高,需要进行技术攻关。
上图来源于jmeter的官方网站,可以从其导航菜单看出,仅提供了用户使用手册、java DOC
问题探究
通过研究jmeter软件架构和脚本的结构,发现其软件核心在ApacheJmeter_core.jar, ApacheJmeter_components.jar这两个jar包上,它们分别的功能如下:
- ApacheJmeter_core.jar,定义Jmeter所有的核心接口、工具类、报表生成逻辑、通用的断言、执行相关逻辑……
- ApacheJmeter_components.jar,定义通用GUI组件、菜单控制、GUI界面的渲染、表单的生成逻辑……
而jmeter的脚本则是在统一的规范下生成的,如下图:
图中是测试计划的插件标签脚本,它包含了guiclass和testclass两个核心的通用属性,外加其它不同数据类型的字段,其它的插件也是同样的格式,它们分别的含义如下:
1.标签上属性均为通用属性,这些属性是由ApacheJmeter_core.jar中的AbstractJMeterGuiComponent类定义,其中:
- guiclass表示jmeter在GUI模式渲染该插件时使用哪个类;
- testclass表示jmeter在执行脚本到该插件时使用哪个类;
- testname是插件的自定义名称;
- enabled表示是否启用该插件,只有enabled为true的插件都会被执行。
2. 标签下的子标签表示该插件的自定义属性,由插件的开发厂商根据插件的功能自己确定。
综合以上的分析结果,可以发现,想要在测试平台上集成jmeter脚本编排,核心的便是研究每一个插件的guiclass,确定属性的定义及值的约束规则。确定完以上的技术要点就完成了二次开发技术攻关,剩下的只有对需要二次开发插件的表单字段的默认值确定、约束规则确认。
技术攻关完成了,下面来到下一个主题,如何构造一个jmeter脚本?观察下面的jmeter脚本代码:
在前面的插件标签脚本中有讲到,所有的jmeter插件都是由通用属性加上自定义属性表示,在通用属性中定义的guiclass会定义插件的字段,但是jmeter的字段是和gui插件深度绑定的,如果为了编排插件引入guiclass类的初始化,会额外增加大量的内存开销,这里就需要做一些变动,当确认完guiclass类中的插件字段后,渲染脚本的时候直接绕开它,使用自定义的方式来组装插件字段。
Jmeter拥有大量的插件,包括官方的和第三方的,数量众多,插件在脚本中的位置也不是固定不变的,这带来了两个问题:
- 插件太多,必须要有一个统一的构建方式构建插件,以不变应万变;
- 编排的脚本中插件的层级无法事先确定。
针对第一个问题,轮到设计模式出场,23种设计模式中的建造者模式正好可以适应这种需要以不变应万变的场景。
注释:建造者模式(Builder Pattern)又叫生成器模式,其定义为:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
针对第二个问题,虽然脚本中插件的层级无法事先确认,但是在jmeter客户端可以确定任何一个插件的下一级插件有哪些,这个时候轮到递归出场。
解决方案示例
综合以上所有的问题分析,做完了所有的前置准备工作后,可以开始插件的组装逻辑的编写,下面以TestPlan插件为例:
递归遍历插件表单封装,通过事先确定的jmeter插件层级并封装在插件json中,遍历时可以很容易控制任务层级的插件字段的封装。
建造者构造插件字段,通过建造者模式提供统一的抽象,屏蔽jmeter底层,只需要调用对应插件的Builder就可以构建相应的插件脚本。
总结
通过以上关于jmeter二次开发整个研究流程,可以将技术性问题的处理流程总结如下:
- 描述清楚需求,给出初步的技术方案;
- 针对技术方案做分析,找出可能存在的技术难点;
- 针对每一个技术难点,从不同的角度分析并找到问题的解决方案;
- 针对每一个解决方案做技术论证,论证方案可行性,确定最终的解决方案;
- 综合各个解决方案,进行综合论证,确定整个大的方案是可行的;
- 实施方案,通过单元测试验证所有的逻辑是符合需求。
其他优质文章
来源:oschina
链接:https://my.oschina.net/u/4026796/blog/4301412