接口测试 dubbo 接口测试技术

思寒_seveniruby · 2017年10月18日 · 最后由 CoraPeng 回复于 2021年11月04日 · 6604 次阅读

dubbo 是什么

dubbo 是阿里巴巴开源的一套 rpc 方案,以为理念很契合微服务,这几年很火,用户里面不凡京东,当当,去哪儿等大公司。
rpc 场景

dubbo 架构

官网也提供了一个很简单实用的 demo 来演示 dubbo 协议的使用,用起来的确很简单强大。

dubbo demo

可参考 http://dubbo.io/ 首页的例子已经很好了。

基于 telnet 的简单调试接口

任何一个 dubbo 服务都支持一个简单的 telent 交互。比如

telnet localhost 20880
>ls -l
> ls -l DemoService
> invoke DemoSerivce.sayHello("seveniruby")

这种方式只能用来简单验证接口的可用

传统的基于 xml 配置的 dubbo 的测试方法

首先创建一个 xml 文件放到 resources 下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <dubbo:application name="demo-consumer"/>
    <dubbo:registry address="dubbo://127.0.0.1:9090"/>
    <dubbo:reference id="demoService" interface="com.testerhome.tapi.dubbo.DemoService"/>
</beans>

通过使用一份 xml 配置文件进行测试

test("dubbo use registy xml"){
  val context = new ClassPathXmlApplicationContext("dubbo/consumer.xml")
  context.start()
  val demoService = context.getBean("demoService").asInstanceOf[DemoService]
  println(demoService.sayHello("seveniruby"))

  val req=new RequestModel()
  req.setName("james")
  req.getChild.setName("lily")
  println(TData.toJson(demoService.reqModel(req)))
}

基于 api 的 dubbo 测试方法

其实除了 xml 配置之外,官方也提供了一份直接通过 api 进行配置的方式,这个方式无疑是可编程比较灵活的

test("dubbo use registry"){
  // 当前应用配置
  val application = new ApplicationConfig
  application.setName("yyy")

  // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接

  // 引用远程服务
  val reference = new ReferenceConfig[DemoService] // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
  reference.setApplication(application)
  reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
  reference.setInterface(classOf[DemoService])
  //reference.setUrl("dubbo://127.0.0.1:20881")
  reference.setTimeout(5000)

  // 和本地bean一样使用DemoService
  val DemoService = reference.get // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
  System.out.println(DemoService.sayHello("seveniruby"))

  val req=new RequestModel()
  req.setName("james")
  req.getChild.setName("lily")
  System.out.println(TData.toJson(DemoService.reqModel(req)))
}

泛化调用

官方原话是

泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过 GenericService 调用所有服务实现。

这种情况适合自己打造接口测试框架使用。以上 2 个方式都需要依赖研发提供的 dubbo 接口的 jar 包,这无疑会增加项目的负担。
使用泛化可以不依赖任何研发提供的 jar 包,不过缺点也明显,仍然需要 jar 包或者其他的文档去分析 dubbo 接口的调用参数信息。
例子

test("泛化调用 by provider conf use map"){

  var reference = new ReferenceConfig[GenericService]() // 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
  reference.setGeneric(true) // 声明为泛化接口
  reference.setApplication(new ApplicationConfig("generic-provider"))
  //reference.setRegistry(registry)
  reference.setInterface("com.testerhome.tapi.dubbo.DemoService") // 弱类型接口名
  reference.setTimeout(5000)
  reference.setUrl(s"dubbo://127.0.0.1:20881")

  val genericService = reference.get
  val result = genericService.$invoke("sayHello", Array("java.lang.String"), Array("xxxx".asInstanceOf[AnyRef]))
  log.info(result)

  val childMap= mutable.Map[String, AnyRef]()
  childMap.put("name", "children")
  val map= mutable.Map[String, AnyRef]()
  map.put("name", "aaa")
  map.put("id", "11")
  map.put("child", childMap.asJava)

  val resModel=genericService.$invoke(
    "reqModel",
    Array("com.testerhome.tapi.dubbo.RequestModel"),
    Array(map.asJava.asInstanceOf[AnyRef]))
  log.info(resModel)
  log.info(TData.toJson(resModel))
}

虽然看起来还是依赖 jar 包,不过这个依赖就挺小了。如果你技术稍微 “猥琐” 点,就应该可以想到,只需要借助 asm 之类的字节码分析框架即可自动生成接口测试用例模板了。

dubbo 测试的技术关注点

  • dubbo 支持很多的协议,如果用的是 http 或者 hessian 协议,他们本身是文本的,可以直接使用 restassured 框架进行接口测试
  • dubbo 的 registry 保存了 dubbo 各种服务的注册信息,测试的时候可以直接用 registry,而不是直接连接到提供服务的 provider 上
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 9 条回复 时间 点赞

typo: telent

对于使用 python 的哥们,使用 telnetlib 搭建 dubbo 测试框架非常好用,亲测有效!不过有个限制就是 dubbo 的接口必须都是接受 string 类型的请求参数!

如果是自定义类型参数,或者泛型的话,就不能用 telnet 了(因为 telnet 是完全模式用户操作,最后输入一定是 string 类型)。

学习了,赞

最近做 dubbo 接口测试, 发现 telnet 和泛化调用返回过来的结果字段不一致, 不知道是什么原因导致, 序列化吗?
还有个问题请教下, 像 dubbo 接口的测试用例应该如何设计, 从入参, 逻辑处理和返回这三个方面吗? 因为没有文档支持 , 感觉不好做 , 没有什么思路.

回复

还有个问题请教下, 有没有更灵活方便完整的方法去获取 dubbo 的服务以及方法列表, 目前我都是直接写脚本 telnet 到服务端口获取或者从 zk 获取.

参数是对象,还不是需要依赖 jar 包?

guoxd 回复

泛型一样可以

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 14:44
simple [精彩盘点] TesterHome 社区 2018 年 度精华帖 中提及了此贴 01月07日 12:08

这个工具比较自动化,感觉方便点
https://github.com/everythingbest/dubbo-postman

请问一下,有没有遇到过这种情况啊?

invoke disabled,不知道什么原因。网上也查不到😭

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册