草帽路飞UU 发表于 2022-11-15 16:24:30

如何用Jmeter实现RPC接口测试简洁化需求?

本帖最后由 草帽路飞UU 于 2022-11-15 16:26 编辑

根据需求,产品部分功能采用thrift-RPC协议进行接口的增、删、改、查,前期采用Junit对其进行测试,为了提高RPC接口测试的简洁化和后期的性能测试需求,打算通过Jmeter的java类测试实现。


  前期准备

  开发提供了IDL描述的Thrift文件:dataService.thrift,其中定义了相关接口函数及数据类型,如下:

enum VStatus {

    ON,

    OFF

}


struct VData {

    1: required string tablename;

    2: required string time;

    3: required string jsons;

    4: optional VStatus status;

}


struct VCondition {

    1: required string tablename;

    2: required i64 starttime;

    3: required i64 endtime;

}


service DataService {

    string write(1: VData data);

    string read(1: VCondition condition);

}



  在本地部署thrift.exe并设置环境变量,之后在dataService.thrift所在的目录下执行:

thrift -r -gen java dataService.thrift            //备注:我这里是用java语言;


  执行成功后在该目录下产生gen-java文件夹,打开该文件夹至api目录下,生成4个文件:DataService.java、VCondition.java、VData.java和VStatus.java。


  基于Jmeter的jar代码编写

  创建Maven项目,编辑pom.xml添加依赖,如下所示:

<dependencies>

    <dependency>

      <groupId>org.apache.thrift</groupId>

      <artifactId>libthrift</artifactId>

      <version>0.11.0</version>

    </dependency>


    <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter</artifactId>

    </dependency>

    <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-test</artifactId>

    </dependency>   

       <dependency>

         <groupId>org.apache.logging.log4j</groupId>

         <artifactId>log4j-api</artifactId>

         <version>2.8.2</version>

       </dependency>

       <dependency>

         <groupId>org.apache.logging.log4j</groupId>

         <artifactId>log4j-core</artifactId>

         <version>2.8.2</version>

       </dependency>         


   </dependencies>



  之后手动加载本地Jmeter版本目录\Jmeter_Home\lib\ext中的ApacheJMeter_core.jar和ApacheJMeter_java.jar作为外部依赖包(注:直接maven加载相关版本的依赖包执行时存在冲突)。

  将之前生成的4个java文件导入项目,设置包名为:com.test.thrift.api,在项目包名下创建ReadRPC.java类,根据Jmeter中java类要求需要继承 AbstractJavaSamplerClient,代码如下:

package com.test.RPCTest;


import com.test.thrift.api.DataService;

import com.test.thrift.api.VCondition;


import org.apache.jmeter.config.Arguments;

import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;

import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;

import org.apache.jmeter.samplers.SampleResult;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TProtocol;

import org.apache.thrift.transport.TSocket;

import org.apache.thrift.transport.TTransport;


public class ReadRPC extends AbstractJavaSamplerClient{

    private TTransport tTransport;

    private DataService.Client dataService;

    private TProtocol tProtocol;

    private VCondition vCondition;


    @Override      

    public Arguments getDefaultParameters(){//默认参数值,包括服务ip、端口、目标表、起止时间等

      Arguments arguments=new Arguments();

      arguments.addArgument("IP", "127.0.0.1");

      arguments.addArgument("Port", "8888");

      arguments.addArgument("TableName", "vle::test.trpc");

      arguments.addArgument("StartTime", "1539752449");

      arguments.addArgument("EndTime", "1539752449");

      return arguments;

    }


    @Override

    public void setupTest(JavaSamplerContext context) { //初始化参数,并通过TTransport模式TBinaryProtocol二进制协议与服务端建立连接

      // TODO Auto-generated method stub

      String ip=context.getParameter("IP");

      int port=context.getIntParameter("Port");

      String tableName=context.getParameter("TableName");

      long startTime=context.getLongParameter("StartTime");

      long endTime=context.getLongParameter("EndTime");

      tTransport=new TSocket(ip,port,30000);

      vCondition=new VCondition();

      try {

            tTransport.open();


            tProtocol=new tBinaryProtocol(tTransport);

            dataService=new DataService.Client(tProtocol);

            vCondition.setTablename(tableName);

            vCondition.setStarttime(startTime);

            vCondition.setEndtime(endTime);

      } catch (Exception e) {

            // TODO: handle exception

      }

      super.setupTest(context);

    }


    @Override

    public SampleResult runTest(JavaSamplerContext context) {

      // TODO Auto-generated method stub

      SampleResult sampleResult = new SampleResult();

      sampleResult.setDataEncoding("utf8");

      sampleResult.sampleStart();

      try {

            String msg=dataService.read(tCondition);//执行读操作,返回响应结果信息到msg


            if(null==msg){//为空判断

                sampleResult.setSuccessful(false);

                sampleResult.setResponseMessage("响应结果为空!");

                sampleResult.setSampleLabel("RPC读取");

                sampleResult.setResponseOK();

                sampleResult.setResponseData("响应结果为空!");

                sampleResult.setDataType(SampleResult.TEXT);

                return sampleResult;

            }

            else {

                sampleResult.setSuccessful(true);

                sampleResult.setSampleLabel("RPC读取");

                sampleResult.setResponseOK();

                sampleResult.setResponseData(msg);

                System.out.println("msg="+msg);

                sampleResult.setDataType(SampleResult.TEXT);

                return sampleResult;

            }


      } catch (Exception e) {


            // TODO: handle exception

            sampleResult.setSuccessful(false);

            e.printStackTrace();

      }

      finally{

            sampleResult.sampleEnd();

      }

      return sampleResult;

    }


    public void teardownTest(JavaSamplerContext context){

      tTransport.close();//关闭连接

      super.teardownTest(context);

    }


}


  在main函数中调用ReadRPC相关函数,代码如下:

    public static void main( String[] args )

    {

      JmeterRPC jrpc=new JmeterRPC();

      jrpc.read();


    }


    public void read(){

      Arguments arguments=new Arguments();

      arguments.addArgument("IP", "127.0.0.1");

      arguments.addArgument("Port", "8888");

      arguments.addArgument("TableName", "vle::test.trpc");

      arguments.addArgument("StartTime", "1539752449");

      arguments.addArgument("EndTime", "1539752449");

      JavaSamplerContext context=new JavaSamplerContext(arguments);

      ReadRPC rpc=new ReadRPC();

      rpc.setupTest(context);

      rpc.runTest(context);

      rpc.teardownTest(context);

    }



  运行程序输出msg=[{".........相关响应数据.............."}]。调试成功后保存后,选中项目右键“Export”->“Java”->“Runnable JAR file”,点击“Next”,设置输出路径和依赖库,如下图所示:




备注:选择第一种方式将依赖包打在里面。


  将打好的RPC.jar包拷贝到JMeter_Home\lib\ext下,启动jmeter控制台打印该jar信息,如下图所示:





启动完成后添加Java请求,显示读取类名,配置相关参数,如下图所示:




执行结果如下:




之后便可以通过该jar进行RPC相关接口测试,而且保证其他测试人员无需写代码便可进行测试。




页: [1]
查看完整版本: 如何用Jmeter实现RPC接口测试简洁化需求?