🎉 🎂 🍰 TesterHome 创立 9 周年纪念日 🍰 🎂 🎉

自动化工具 纯 python 编写的一套 dubbo 测试平台

兔子 · 2018年11月01日 · 最后由 Richard 回复于 2020年03月17日 · 760 次阅读

因组织要求,需要一个 Dubbo 接口的测试工具,经多方研究,遂决定要写一个不需要编写任何代码,直接在页面上填写数据就能直接运行 Dubbo 接口的测试工具,类似于 Postman 编写 http 接口一样简单。

  • 整个平台采用 B/S 结构,后台服务采用的是 python 的 django 框架
  • 传输方式为 TCP + Hessian
  • 平台没有用到 zk,都是直接在前端页面填写 IP:PORT 直连的

目前实现的功能:

  1. 解析相关 jar 包,把接口、函数、函数参数直接显示在 web 界面
  2. 每个版本接口、函数的对比,并在 web 界面显示差异
  3. 可直接在界面上填写需要的数据,一键完成数据整理、发送,包含返回数据的显示
  4. 现已支持 java 大部分的数据类型,不仅包括基础类型(String、Boolean、Byte、Double、Integer、Date、Void)等;容器类型(Map、HashMap、List、HashSet、Vector)等;还支持 Object 对象的传递,包含 Enum;对于泛型或者一些特殊在运行过程中才知道的对象,web 界面可以支持测试人员自定义对象属性
  5. 用例的创建

后期准备实现的功能:

  1. 用例的断言
  2. 测试计划
  3. 创建 mock 数据服务
  4. 完全自定义接口、函数及函数参数

接口列表界面

函数列表界面

用例添加和调试界面

自定义数据结构界面

需要考虑的点

  • 由于 python 的 Dict 类型,key 不支持 List 和 Dict 类型,主要是 List 和 Dict 类在 python 中没有实现__hash__,故自定义一个类,实现一个__hash__函数,其他继承这两个类就可以了
class PDict(dict):
    def __hash__(self):
        return id(self)

class PList(list):
    def __hash__(self):
        return id(self)
  • 由于前后端传输的类型我们选择是 json 格式,而且 json 能存储的类型有限,由于我们在 json 格式的数据中自定义了一套我们自己的数据结构,后台会把前端传给我们的 json 数据再进行二次编译,编译成 java 所需要的各种数据类型

比方说 java 中的数据类型为:
这里表示有三个参数,第一个参数为 Dict 类型,第二个参数为 String 类型,第三个参数为自定义枚举类型

Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;Ljava/lang/String;Lcom/test/enums/DataAPIEnum;

翻译成前后端都认识的类型为:

[{"valueMetaType": "", "keyChildren": [{"children": [], "type": "String", "name": "String", "metaType": ""}], "name": "Map", "keyType": "String", "valueChildren": [{"metaType": "", "type": "Object", "children": [], "name": "Object"}], "keyMetaType": "", "valueType": "Object"}, {"metaType": "", "type": "String", "children": [], "name": "String"}, {"metaType": "com/test/enums/DataAPIEnum", "type": "Enum", "children": [], "name": "Enum"}]

然后把需要的值填入上述 json 里面的 children 字段就好,这个大家看过就好,没准你们就更好的想法也不一定

  • hessian 协议的 pack 与 unpack:这里我参考的是 github 上大神的代码,做了二次开发,调试过程中也针对性的修改了一些东西,地址:https://github.com/zhouyougit/PyDubbo

PS

  • 由于重重原因,(哎……😩 )代码暂时还开源不了,不过大家有兴趣的话,可以一起讨论讨论,知无不言,言无不尽
共收到 11 条回复 时间 点赞

大佬,学习一个

Felix 回复

也不算大佬,你只要把我上面贴的 github 连接,然后反着考虑,你也能弄出来;
当初的想法是,让不会写代码的人也可以测试 Dubbo 接口

仅楼主可见
昨天有雨 回复

其实 Dubbo 服务的本质还是在服务器上监听了一个端口,然后你按照你 hessian 协议把数据打包好后,就往这个端口发送过去就可以了
这么来考虑的话,你只需要在后台启动一个 sock 链接,连接到 Dubbo 那个服务器,这是连接的部分
下面我来贴一个数据打包的结构吧,这是整个包的数据结构,分先后,具体的 hessian 是怎么打包的,建议看看 hessian 的官方文档:http://hessian.caucho.com/doc/hessian-ws.html

[
  {
    "HEADER": {
      "struct": "12ds",
      "value": "dabbc2000000000000000000",
      "desc": "不足12位后面补0"
    }
  },
  {
    "dataLength": {
      "struct": "uint32",
      "value": "",
      "desc": "数据长度"
    }
  },
  {
    "DOUBLE_VERSION": {
      "struct": "根据hessian协议序列化",
      "value": "2.5.3",
      "desc": ""
    }
  },
  {
    "interface": {
      "struct": "根据hessian协议序列化",
      "value": "com.test.account.service",
      "desc": "接口名称"
    }
  },
  {
    "interfaceVersion": {
      "struct": "根据hessian协议序列化",
      "value": "2.0",
      "desc": "Dubbo服务的版本号,就是在被测服务xml里面写的那个"
    }
  },
  {
    "methodName": {
      "struct": "根据hessian协议序列化",
      "value": "getScoreMemberInviteInfo",
      "desc": "函数名"
    }
  },
  {
    "paramType": {
      "struct": "根据hessian协议序列化",
      "value": "Ljava/lang/String;",
      "desc": "参数类型"
    }
  },
  {
    "param": {
      "struct": "根据hessian协议序列化",
      "value": "sss",
      "desc": "参数值"
    }
  },
  {
    "attachments": {
      "struct": "根据hessian协议序列化",
      "value": {
        "customer": "python-dubbo-test",
        "owner": "tbj-test",
        "timeout": 5
      },
      "desc": ""
    }
  }
]

还好我司用的是 springcloud

关键是只有支持 hessian 方式的类库,应用范围窄

可以参考一下 dubbo 官方 telnet 治理服务

chuanqiong 回复

dubbo 的 telnet 服务,我粗略看了一下

  • 很复杂的参数调用我一直没有调试成功
  • 找方法参数的时候,telnet 只能给到java.util.List,而我需要给到Ljava/util/List<Ljava/lang/String;>;

其他的没仔细研究,可能我研究的不深,所以就没有用自带的 telnet

嘿嘿……想用其他类库的,可以在后端加,前端只需要加一条协议,来表明这次请求需要哪种类库不就可以了😇

推荐一个方便的 dubbo-postman 工具~😀
https://www.jianshu.com/p/11048224be1a

11楼 已删除
仅楼主可见
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册