如何构建一个Dubbo接口测试的通用框架(https://github.com/nitibu/jmeter-dubbo-test

从上面的流程我们可以看出,测试类大致的一个结构:

  • 使用json文件来构造测试数据
  • java程序只对json文件进行解析
  • 接口调用成功后,用json文件中的期望数据来对接口返回数据进行比对,判断调用是否成功

json文件的定义

  1. {
  2. "Connection": {
  3. "URL": "101.219.255.73:50883",
  4. "SERVICE_NAME": "com.company.mdapi.sdk.material.export.MaterialApiService",
  5. "VERSION": "1.0.0",
  6. "METHOD": "queryUnboundListByPage",
  7. "HELPCLASS": "com.utils.common.helper.MaterialApiService.QueryUnboundListByPageHelper"
  8. },
  9. "Random": false,
  10. "Args": {
  11. "sourceSystem": 2,
  12. "querySourceSystem": null,
  13. "materialCode": "MD_S6006",
  14. "materialName": null,
  15. "materialType": null,
  16. "pkId": null,
  17. "shipperCode": "ZA01",
  18. "storageCenterCode": "HZA1",
  19. "pager": {
  20. "page": 1,
  21. "rows": 5,
  22. "totalCount": null,
  23. "pageOffset": null,
  24. "sort": "ID",
  25. "order": "ASC",
  26. "totalPage": null,
  27. "pageCode": 7,
  28. "startPageIndex": null,
  29. "endPageIndex": null,
  30. "previewPage": null,
  31. "nextPage": null
  32. }
  33. },
  34. "Verify": false
  35. }

参数具体定义:

  • Connection:Dubbo服务的地址URL、服务名称SERVICE_NAME、版本号VERSION、远程接口调用的方法METHOD、
    数据转化处理的辅助类HELPCLASS。
  • Random:用来是能随机数设置,压力测试类似Add数据库操作时可以绕过数据库预设好的唯一性校验。
  • Args:调用接口时,传入的参数,这里提供的参数需要在辅助类中转换成接口参数,然后调用接口。
  • Verify:保留值,暂无使用

Java程序实现数据转换及接口调用

  • 辅助的Help类,需要继承SampleHelper类,同时实现其中的两个抽象方法readJsonFile和callRemoteMethod,
    分别用来读取json配置文件和调用远程方法(实际测试人员只需要实现这两个方法就可以进行Dubbo接口测试)。
  1. public class AddMaterialListHelper extends SampleHelper<Result<List<FailData>>> {
  2.  
  3. public static final String[] RANDOM_FIELD = {"materialCode","materialName"};
  4.  
  5. @Override
  6. public Map<String, Object> readJsonFile(String jsonPath) {
  7. JsonParser parser = new JsonParser();
  8.  
  9. try {
  10. JsonObject json=(JsonObject) parser.parse(new FileReader(jsonPath));
  11. Map<String, Object> values = new HashMap<String, Object>();
  12. UtilsHelper.getInstance().getConnectionArgument(values, json);
  13.  
  14. JsonObject args=json.get("Args").getAsJsonObject();
  15. if (!args.get("data").isJsonNull()) {
  16. String jsonArray = args.get("data").getAsJsonArray().toString();
  17. //TODO
  18. Gson gson = new Gson();
  19. @SuppressWarnings("serial")
  20. List<MaterialInterfaceDTO> dtoList = gson.fromJson(jsonArray,
  21. new TypeToken<List<MaterialInterfaceDTO>>() {
  22. }.getType());
  23. RandomNum.setRandom(json , RANDOM_FIELD , dtoList);
  24. values.put("data", dtoList);
  25. }
  26.  
  27. if (!args.get("sourceSystem").isJsonNull()) {
  28. values.put("sourceSystem", new Integer(args.get("sourceSystem").getAsInt()));
  29. }
  30.  
  31. return values;
  32.  
  33. } catch (JsonIOException e) {
  34. e.printStackTrace();
  35. } catch (JsonSyntaxException e) {
  36. e.printStackTrace();
  37. } catch (FileNotFoundException e) {
  38. e.printStackTrace();
  39. }
  40. return null;
  41. }
  42.  
  43. @Override
  44. public Result<List<FailData>> callRemoteMethod(Object object, Map<String, Object> values) {
  45. MaterialInterfaceService service = (MaterialInterfaceService) object;
  46. @SuppressWarnings("unchecked")
  47. Result<List<FailData>> callResult = service.addMaterialList (
  48. (int) values.get("sourceSystem"),
  49. (List<MaterialInterfaceDTO>) values.get("data"));
  50. return callResult;
  51. }
  52. }

  • 这里有个注意点,由于个博主所在的团队把接口参数封装成了一个可序列化的class类,所以需要进行数据转化,有些公司的
    接口参数直接传json字符串,那么只需要把json转换为字符串进行传参就可以。

    参数封装为序列化的class类:

    1. public class MaterialInterfaceDTO implements Serializable {
    2. private static final long serialVersionUID = -3725469669741557392L;
    3. private String materialCode;
    4. private String materialName;
    5. private Integer materialType;
    6. private Integer importFlag;
    7. private String sixNineCode;
    8. private Long expirationDate;
    9. private Long packingSpecification;
    10. private String basicUnit;
    11. private String minSaleUnit;
    12. private String basicUnitName;
    13. private String minSaleUnitName;
    14. private String materialImageUrl;
    15. private Integer transportFlag;
    16. private Integer sourceSystem;
    17. private String createName;
    18. private String updaterName;
    19.  
    20. public MaterialInterfaceDTO() {
    21. }
    22.  
    23. public String getMaterialCode() {
    24. return this.materialCode;
    25. }
    26.  
    27. public void setMaterialCode(String materialCode) {
    28. this.materialCode = materialCode;
    29. }
    30.  
    31. public String getMaterialName() {
    32. return this.materialName;
    33. }
    34.  
    35. public void setMaterialName(String materialName) {
    36. this.materialName = materialName;
    37. }
    38.  
    39. public Integer getMaterialType() {
    40. return this.materialType;
    41. }
  • 在init中通过java反射机制,获取json配置文件中设置好的辅助类的对象,然后在runTest中调用对应辅助类中
    callRemoteMethod,返回的结果解析后放到SampleResult的responeData,用来在jmeter中使用后置处理器进行
    结果判断。

    1. package com.utils.common;
    2.  
    3. import com.alibaba.dubbo.config.ApplicationConfig;
    4. import com.alibaba.dubbo.config.ReferenceConfig;
    5. import com.google.gson.JsonObject;
    6. import com.google.gson.JsonParser;
    7. import org.apache.jmeter.config.Arguments;
    8. import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
    9. import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
    10. import org.apache.jmeter.samplers.SampleResult;
    11.  
    12. import java.util.Map;
    13.  
    14. public class RunMethodTest extends AbstractJavaSamplerClient {
    15. private static String JMX_PATH = null;
    16. private static String TAG = Thread.currentThread().getStackTrace()[1].getClassName();
    17. private SampleHelper helper = null;
    18. private Map<String, Object> values = null;
    19. private Map<String, Object> config = UtilsHelper.getInstance().getConfigProperties();
    20. private String ARGS_FILE;
    21. private Object object;
    22.  
    23. public void setupTest(){
    24. //定义测试初始值,setupTest只在测试开始前使用
    25. System.out.println("setupTest");
    26. }
    27.  
    28. public void init() {
    29. // 当前应用配置
    30. ApplicationConfig application = new ApplicationConfig();
    31. application.setName(TAG);
    32.  
    33. // 获取具体参数配置路径
    34. if ("true".equals(config.get("DEBUG").toString())) {
    35. JMX_PATH = ARGS_FILE;
    36. } else {
    37. JMX_PATH = UtilsHelper.getInstance().getScriptPath(config.get("SCRIPT_HOME").toString(), ARGS_FILE);
    38. }
    39. Map<String, Object> helpArgs = UtilsHelper.getInstance().getHelpClassAndMethod(JMX_PATH);
    40. helper = (SampleHelper)UtilsHelper.getInstance().invokeStaticMethodByReflect(
    41. (String) helpArgs.get("HELPCLASS"),
    42. (String) helpArgs.get("HELPMETHOD")
    43. ) ;
    44.  
    45. values = helper.readJsonFile(JMX_PATH);
    46.  
    47. // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
    48. // 引用远程服务,配置dubbo服务版本、服务名称、url地址
    49. ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
    50. reference.setApplication(application);
    51. reference.setTimeout(20000);
    52. reference.setVersion(values.get("conn_version").toString());
    53. reference.setInterface(values.get("conn_service_name").toString());
    54. reference.setUrl(values.get("conn_url").toString());
    55.  
    56. // 和本地bean一样使用xxxService
    57. object = reference.get(); // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用\
    58. }
    59.  
    60. public SampleResult runTest(JavaSamplerContext arg0) {
    61. SampleResult sr = new SampleResult(); ;
    62. try {
    63. //获取参数
    64. ARGS_FILE = arg0.getParameter("ARGS_FILE");
    65.  
    66. //dubbo初始化
    67. init();
    68.  
    69. //jmeter结果对象
    70. // sr.setSampleLabel(TAG);
    71. sr.sampleStart();
    72. sr.setSuccessful(true);
    73.  
    74. String res = helper.handleResult(helper.callRemoteMethod(object, values));
    75.  
    76. sr.sampleEnd(); // jmeter 结束统计响应时间标记
    77. if (res != null) {
    78. JsonObject response = new JsonParser().parse(res).getAsJsonObject();
    79. System.out.println("\n*************测试返回值****************\n");
    80. System.out.print(response.toString()+"\n");
    81. if (response.get("code").getAsInt() != 0) {
    82. sr.setSuccessful(false);
    83. }
    84. sr.setResponseData(response.toString(), "UTF-8");
    85. // if (null != response.get("data")) {
    86. // sr.setResponseData(response.get("data").toString(), "UTF-8");
    87. // System.out.print(response.get("data").toString()+"\n");
    88. // } else if (null != response.get("result")) {
    89. // sr.setResponseData( response.get("result").toString(), "UTF-8");
    90. // }
    91. } else {
    92. System.out.print("handleResult return null\n");
    93. }
    94.  
    95. } catch (Exception e) {
    96. e.printStackTrace();
    97. sr.setResponseCode("999");
    98. sr.setResponseMessage(e.getMessage());
    99. sr.setSuccessful(false);
    100. }
    101. return sr;
    102. }
    103.  
    104. public Arguments getDefaultParameters(){
    105. //参数定义,显示在前台,也可以不定义
    106. Arguments params = new Arguments();
    107. params.addArgument("ARGS_FILE", "");
    108. return params;
    109. }
    110.  
    111. public void teardownTest(JavaSamplerContext arg0){
    112. super.teardownTest(arg0);
    113. }
    114.  
    115. }

【Jmeter测试】使用Java请求进行Dubbo接口的测试的更多相关文章

  1. jmeter中实现java请求实战日志

    view code public class JdbcInsert implements JavaSamplerClient { // 全局变量 PreparedStatement pstmt; Co ...

  2. 性能测试十一:jmeter进阶之java请求

    使用Java编写JDBC脚本对Mysql进行增删改查等操作的性能测试 使用Jmeter提供的脚本框架依赖的jar包(分别在jmeter目录下的lib和ext目录下) ApacheJMeter_core ...

  3. 想要测试Dubbo接口?测试的关键点在哪里?

    Dubbo接口如何测试? 这个dubbo如何测试,dubbo接口测试什么玩意儿?   RPC的有一个类型,叫Dubbo接口. 那这个接口如何测试?测试的关键点在哪里? 这个面试问题,我觉得大家可能就有 ...

  4. Java面向对象作业-用接口方式测试向下转型

    Java面向对象作业-用接口方式测试向下转型 根据视频的里实例 我们直接修改Test2测试方法: package com.java1234.chap03.sec13; public class Tes ...

  5. 【JMeter】JMeter完成一个java请求的压测

    先定义一下我说的remoteService:即远程调用服务,没有http的url.不对外提供或者对外提供有限的服务.具体视各公司的代码架构所定,比如有些公司为web工程,scf服务,db.scf即为服 ...

  6. jmeter之自定义java请求性能测试

    一.环境准备         1.新建一个java工程         2.导入jar包:ApacheJMeter_core.jar     ApacheJMeter_java.jar         ...

  7. 【转】JMeter完成一个java请求的压测

    JMeter完成java请求的压力测试详解以及问题总结 原文地址:http://www.cnblogs.com/zhaoxd07/p/4895224.html    作者:KK_Yolanda 这篇文 ...

  8. java反射调用dubbo接口

    需求:项目增加幂等 场景:1.三个项目:a .b.c2.a项目加幂等3.b项目dubbo调用项目a的时候超时没有获取返回结果,增加重试机制(非立即重试,3min or 5min 后重试)4.c项目是一 ...

  9. 性能测试十二:jmeter进阶之java请求参数化

    如项目中的ip.端口号之类的,都可以在此代码中定义 public Arguments getDefaultParameters() { // TODO Auto-generated method st ...

随机推荐

  1. leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence

    Longest Increasing Subsequence 最长递增子序列 子序列不是数组中连续的数. dp表达的意思是以i结尾的最长子序列,而不是前i个数字的最长子序列. 初始化是dp所有的都为1 ...

  2. Basic Classifiers and Loss Functions

    Linear Classifier and Hing Loss (or Multiclass SVM Loss) Linear Mapping (Score function) Linear Clas ...

  3. Git--查看,删除,添加远程分支

    1. 查看远程分支: $ git branch -a 2. 删除远程分支: $ git push origin --delete <branch name> 或者 git push --d ...

  4. ZooKeeper系列(2)--基于ZooKeeper实现简单的配置中心

    ZooKeeper节点的类型分为以下几类:  1. 持久节点:节点创建后就一直存在,直到有删除操作来主动删除该节点 2. 临时节点:临时节点的生命周期和创建该节点的客户端会话绑定,即如果客户端会话失效 ...

  5. 工具 | Axure基础操作 No.6

    这个是基础教程最后一篇,但是这仅仅是个开始,需要学的东西还有很多.坚持! 1.生成部分原型页面 不能单独生成子级的页面,会自动的勾选上父级.如果想单独的生成的话,就得把这个页面的级别提高,变成一级页面 ...

  6. PyCharm 2018最新激活码通用

    通用:Window.Mac.Ubantu都稳定有效,关键是这种激活方式不会产生其他影响 缺点:需要修改hosts文件 **1.修改hosts文件**将 0.0.0.0 account.jetbrain ...

  7. Maven插件的简介,安装及在eclipse中配置

    1.Maven简介 1.Maven介绍 Maven是一个基于项目对象模型(POM:project object model)的概念的纯java开发的开源的项目管理工具.Maven把我们的工程抽像一个对 ...

  8. jquery file upload使用

    <!-- jquery file upload相关js --> <script src="/js/jquery-file-upload/js/jquery.ui.widge ...

  9. 同步工具类-----循环栅栏:CyclicBarrier

    import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; impor ...

  10. 将select的默认小三角替换成别的图片,且实现点击图片出现下拉框选择option

    最近做项目,要求修改select下拉框的默认三角样式,因为它在不同浏览器的样式不同且有点丑,找找网上也没什么详细修改方法,我就总结一下自己的吧. 目标是做成下图效果: 图一:将默认小三角换成红圈的三角 ...