最近一直使用jmeter做接口测试,虽然好用,但是每次解析结果都要写大量重复代码。然后想到groovy是可以在运行时动态增强jvm字节码的,比如Date中就有大量增强的方法,比如format,upto,downto......,既然groovy可以,jmeter又能运行groovy,所以就有了下面的内容
新建一个groovy脚本
def current= new Date()
println current.class
current.downto(Date.parse("yyyy-MM-dd","2023-02-01")) {
println it
}
可以看到运行正常
那么groovy到底是怎么做到的呢?
借助idea强大的代码定位功能,找到了downto方法的位置
通过观察groovy模块的包,发现被扩展方法的类所在的包都有一模一样的结构
那么可能这就是groovy能够扩展方法的关键了,接下来就是验证了,考虑到编写好的脚本需要打包,而脚本有可能还有依赖,为了方便操作,这里新建一个gradle项目来验证,(也可以使用maven或ant)
新建一个空的gradle项目,结构如下;
// 依赖添加groovy
implementation 'org.codehaus.groovy:groovy-all:3.0.11'
// 示例用到的第三方依赖
implementation 'com.jayway.jsonpath:json-path:2.7.0'
为了方便后面编写的脚本在的时候将依赖包一起拷贝过去,build.gradle中添加一个拷贝任务
task copyAllDependencies(type: Copy) {
from configurations.compileClasspath.fileCollection {!it.name.toLowerCase().contains("jmeter")&&!it.name.toLowerCase().contains("groovy")}
into "${buildDir}/libs"
}
// 这里选择build任务需要依赖拷贝依赖的任务,这样每次build jar包的时候就会自动拷贝依赖了
build.dependsOn(copyAllDependencies)
这里贴上之前定位代码的详细信息,对比我们调用的代码
// current就是下面方法的第一个参数了,downto里的第一个参数对应下面方法的第二个参数,第二个参数闭包其实对应方法的第三个参数闭包
current.downto(Date.parse("yyyy-MM-dd","2023-02-01")) {
println it
}
接下来开始仿写一个要扩展的方法,新建一个groovy脚本,这里使用的是groovy语法,其实跟上面的结构是一样的
// 因为jmeter目前做接口测试主要用到的报文格式就是json,所以这里就以jsonpath的处理为例
package com.aben.demo.exts
import com.jayway.jsonpath.Configuration
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.Option
class JsonPathExt {
static jsonpath(String self){
return JsonPath.using(Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build()).parse(self);
}
}
接下来在resources目录下创建/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule文件
moduleName=MySelExt
moduleVersion=3.0.11
# 扩展成员方法
extensionClasses=com.aben.demo.exts.JsonPathExt
# 扩展静态方法
staticExtensionClasses=
到这里项目的结构如下图所示
将打包好的jar连同下面的依赖包一同拷贝到groovy的lib目录下,重新启动groovyconsole.bat
验证效果如下:
可以看到jsonpath方法已经扩展成功了
对比两种方式是不是上面的要简单多了