Jmeter压测实战:Jmeter二次开发之自定义函数

1 前言

Jmeter是Apache基金会下的一款应用场景非常广的压力测试工具,具备轻量、高扩展性、分布式等特性。Jmeter已支持实现随机数、计数器、时间戳、大小写转换、属性校验等多种函数,方便使用人员使用。如果在使用过程中存在和业务强耦合的常用功能函数,在Jmeter不支持的情况下,那就需要单独开发自定义函数实现特定功能。

本文介绍如何开发Jmeter自定义函数实现快速生成京东宙斯下单标准sign,同时深刻理解Jmeter的插件化机制及高扩展性特性。

2 开发准备

  1. Java基础开发
  2. Maven基本使用
  3. 开发依赖版本
    JDK 1.8.0Maven 3.6.3Jmeter 5.4.3

3 自定义函数核心实现

3.1 新建项目

pom.xml文件核心配置如下

  • 新建maven项目,这里项目名为:JSF_Sampler
  • 因为是基于Jmeter的扩展,需要依赖包Jmeter两个核心包,分别是:
  • ApacheJMeter_core
  • ApacheJMeter_java
  • ApacehJMeter_functions

pom.xml文件核心配置如下

python 复制代码
<groupId>com.jd.jmeter.jsf</groupId>
<artifactId>JSF_Sampler</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jmeter-version>5.4.3</jmeter-version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_core</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_functions</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
    </dependencies>
3.2 继承实现AbstractFunction类

实现类依次实现以下几个步骤

1)新建实现类并继承 AbstractFunction

2)重写以下方法,每个方法的用途见下方代码注释

  • execute()
  • setParameters()
  • getReferenceKey()
  • getArgumentDesc()
python 复制代码
   /**
     * 京东宙斯 下单标准字段常量
     */
    private static final String APP_KEY = "app_key";
    private static final String APP_SECRET = "app_secret";
    private static final String ACCESS_TOKEN = "access_token";
    private static final String TIMESTAMP = "timestamp";
    private static final String V = "v";
    private static final String METHOD = "method";
    private static final String BUY_PARAM_JSON = "360buy_param_json";
    /**
     * Jmeter中自定义的函数名,在Jmeter的函数助手中可以看到
     */
    private static final String FUNC_NAME = "__GenSignFunction";
 
    /**
     * 自定义函数的描述,入参,出参,方便使用人员参考使用
     */
    private static final List<String> desc = new ArrayList<>();
 
    static {
        desc.add("This function is used to generate the JD's JOS sign value");
    }
 /**
     * 此为自定义函数核心实现类,其中,入参SampleResult为上次运行的结果,Sampler为当前的采集器;
     * 返回值为该函数的返回值
     * @param sampleResult
     * @param sampler
     * @return
   * @throws InvalidVariableException
 */
 @Override
    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
        // 入参处理
        String param = String.valueOf((CompoundVariable)paramValues[0]);
        String signResult = paramHandler(param);
 
        return signResult;
    }
 
    /**
     * 按京东宙斯sign加密规则生成标准sign
     * @param param
     * @return
     */
    public String paramHandler(String param){
        Map<String,String> valueMap = new HashMap();
        // 按&符号分割
        String[] paramArray = param.split("&");
        for (int i = 0; i < paramArray.length-1; i++) {
            String key = paramArray[i].split("=")[0];
            String value = paramArray[i].split("=")[1];
            valueMap.put(key,value);
        };
        // 京东宙斯标准sign
        String josGign = EncryptUtil.getSignature(valueMap.get("app_secret")+BUY_PARAM_JSON+valueMap.get("360buy_param_json")
        +ACCESS_TOKEN+valueMap.get("access_token")
        +APP_KEY+valueMap.get("app_key")
        +METHOD+valueMap.get("method")
        +TIMESTAMP+valueMap.get("timestamp")
        +V+valueMap.get("v")
        +valueMap.get("app_secret"));
        return josGign;
    }
 
/**
* 配置入参,jmeter函数助手入参
*/
    @Override
    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
        paramValues = collection.toArray();
    }
/**
* 此方法返回自定义的函数名称
*/
    @Override
    public String getReferenceKey() {
        return FUNC_NAME;
    }
/**
* 此方法返回函数描述信息
*/
    @Override
    public List<String> getArgumentDesc() {
        return desc;
    }
3.3 最终项目结构

4 Jmeter加载扩展包

以上开发完成,打包此项目,注意这里的打包要包含依赖包。

4.1 maven构建配置
python 复制代码
<build>
        <finalName>${project.artifactId}</finalName>
        <defaultGoal>install</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
4.2 项目打包
  1. 打包指令如下

  2. mvn package -Dmaven.test.skip=true

4.3 Jmeter加载扩展包

将打包后的扩展包放置到Jmeter的ext目录:apache-jmeter-5.4.3/lib/ext/

启动Jmeter后,Jmeter会自动加载ext目录中的扩展包

打开Jmeter函数助手后,可以看到本次实现类中打印的相关日志

5 自定义函数调用调试

5.1 打开Jmeter函数助手,选择自定义函数
5.2 京东宙斯接口验证

这里使用京东快递获取预制运单号接口,输入GET请求后,直接点击运行函数【Generate & Copy to clipboard】,出参返回32位sign值。

python 复制代码
GET请求入参
method=jingdong.etms.waybillcode.get&app_key=349559FAE87E66826499890862E40A44&access_token=c8c2bdc8d1684630bb771a503d5b5a7fkyzh×tamp=2022-01-28 15:10:00&360buy_param_json={"preNum":"1","customerCode":"10K43816","orderType":"0"}&v=2.0&sign=EBB52C6CEDA34703ADE72D4AA4D8F316&app_secret=29959e4cadc14ff4998d4fc26d1e5063

6 总结

本文通过自定义函数实现了京东宙斯下单标准sign的生成,希望通过本项目大家可以学习到:

  • 如何二次开发Jmeter,实现自己特有的自定义函数。
  • 理解为何官方介绍Jmeter是插件化的,高扩展性特性。
  • 更好的理解Jmeter内部处理机制。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关推荐
UTP协同自动化测试8 小时前
物联网模组测试难点 |APP指令下发+UART 响应+GPIO 电平变化,如何一次性验证?
功能测试·嵌入式硬件·物联网·模块测试
wfbcg8 小时前
每日算法练习:LeetCode 209. 长度最小的子数组 ✅
算法·leetcode·职场和发展
yoyobravery9 小时前
蓝桥杯第15届单片机满分
单片机·职场和发展·蓝桥杯
June bug10 小时前
全链路测试
功能测试·面试·职场和发展
倦王10 小时前
力扣日刷47
算法·leetcode·职场和发展
brucelee18612 小时前
使用 JMeter 进行 API 压力测试完整指南
jmeter·压力测试
abant212 小时前
leetcode 239 单调队列 需要一些记忆
算法·leetcode·职场和发展
ZKNOW甄知科技12 小时前
数智同行:甄知科技2026年Q1季度回顾
运维·服务器·人工智能·科技·程序人生·安全·自动化
潘宸 .12 小时前
接口幂等性设计
程序人生·java-ee
DeepNoMind13 小时前
DevOps 2.0:智能体如何接管故障修复和基础设施维护
程序人生