测试开发必备技能之 Dubbo 接口测试技术

40 阅读3分钟

图片

Dubbo 是什么?

图片

霍格沃兹测试学院 TestingStudio

Dubbo 是阿里巴巴开源的一套 RPC 方案,因为理念很契合微服务,这几年很火,用户里面不乏京东、当当、去哪儿等大公司。

RPC 场景


图片

Dubbo 架构

图片

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

霍格沃兹测试学院 TestingStudio

Dubbo Demo


官网首页的例子已经很好了,可参考 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 配置之外,官方也提供了一份直接通过 XML 进行配置的方式,这个方式无疑是可编程、比较灵活的。

霍格沃兹测试学院 TestingStudio

test("Dubbo use registry"){// 当前应用配置val application = new ApplicationConfigapplication.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 一样使用 DemoServiceval 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)))}
  1. 泛化调用

  2. 图片

官方原话是:

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

这种情况适合自己打造接口测试框架使用。以上 2 个方式都需要依赖研发提供的 Dubbo 接口的 jar 包,这无疑会增加项目的负担。

使用泛化可以不依赖任何研发提供的 jar 包,不过缺点也明显,仍然需要 jar 包或者其他的文档去分析 Dubbo 接口的调用参数信息。

霍格沃兹测试学院 TestingStudio

举个例子:

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.getval 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 上。

霍格沃兹测试学院 TestingStudio