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

发表于:2023-8-24 09:39

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:程序员小濠    来源:知乎

  1 前言
  Jmeter是Apache基金会下的一款应用场景非常广的压力测试工具,具备轻量、高扩展性、分布式等特性。Jmeter已支持实现随机数、计数器、时间戳、大小写转换、属性校验等多种函数,方便使用人员使用。如果在使用过程中存在和业务强耦合的常用功能函数,在Jmeter不支持的情况下,那就需要单独开发自定义函数实现特定功能。
  本文介绍如何开发Jmeter自定义函数实现快速生成京东宙斯下单标准sign,同时深刻理解Jmeter的插件化机制及高扩展性特性。
  2 开发准备
  ·Java基础开发
  · Maven基本使用
  · 开发依赖版本
  JDK 1.8.0Maven 3.6.3Jmeter 5.4.3
  3 自定义函数核心实现
  3.1 新建项目
  · 新建maven项目,这里项目名为:JSF_Sampler
  · 因为是基于Jmeter的扩展,需要依赖包Jmeter两个核心包,分别是:
  · ApacheJMeter_core
  · ApacheJMeter_java
  · ApacehJMeter_functions
  pom.xml文件核心配置如下
   <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
  注意:实现类的包名必须包含http://xxx.functions.xxx,Jmeter使用命名规则实现实现类的加载。
  2)重写以下方法,每个方法的用途见下方代码注释
  ·execute()
  · setParameters()
  · getReferenceKey()
  · getArgumentDesc()
      /**
       * 京东宙斯 下单标准字段常量
       */
      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构建配置
   <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 项目打包
  打包指令如下:
  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值。
  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内部处理机制。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号