基于微服务架构的自动化测试
2019-04-26张圆冰
文/张圆冰
随着软件技术架构发展,软件系统的复杂程度也越来越高。传统的单体应用架构耦合度高,设计、开发、部署为一个整体的单元,部分更新都需要重新部署整个应用。随着应用功能升级,维护、升级、新增功能都会变得越来越困难,很难以敏捷研发模式进行开发和发布,进而导致软件功能升级效率低下。所以微服务架构应运而生。微服务的颗粒比较小,一个大型复杂软件应用由多个微服务组成,每种服务只做一件事,是一种松耦合的能够被独立开发和部署的无状态化服务(独立扩展、升级和可替换),不同服务通过一些轻量级交互机制来通信,最终构建出实现完整功能的软件系统。
微服务这种细粒度的特性,为功能升级带来便利的同时,给软件测试提出了较大的挑战。主要体现在两方面:
(1)微服务架构将服务拆分成数量众多的接口,大量接口的快速迭代需要良好的自动化测试体系予以支撑;
(2)不同服务接口之间开发独立,但又需要彼此通信,因此单接口的测试,如何避开外部接口变动的影响,也是需要思考的。本文主要就这两方面问题进行了探索和实践。
1 微服务架构简述
图1:整体应用架构示意图
图2:微服务架构示意图
微服务架构是相对传统软件架构而言的。传统软件架构可以看成一个完整的单元。一般由用户界面,后台服务端应用和数据库三层结构组成。服务端应用是完整的,是一个单独的的逻辑执行;数据库是由许多表构成一个通用的、相互关联的数据管理系统。应用服务程序接收客户端输入,计算处理后检索并更新数据库中数据。这是一种自然而然的构建系统的思路,所有的功能实现模块都集合在一起,通过负载均衡将多个应用部署到多台服务器上。传统架构在长期以来的软件架构设计中被广泛使用,并获得成功。整体应用架构示意图如图1所示。
但是,随着软件快速迭代要求提升,以及云部署技术的广泛使用,整体应用程序面临着变更应用程序的一小部分,却要求整个应用重新构建和部署的问题。随着时间的推移,很难再保持一个好的模块化结构,使得一个模块的变更很难不影响到其它模块。所以,以服务为单元拆分整体架构,形成一个个单独功能模块,可以独立部署与修改,即我们通常说的微服务架构逐渐出现并为一些行业先行者应用到软件系统设计中来。微服务架构倾向围绕业务功能的组织来分割服务,在这个功能模块中涉及到的技术、数据存储、用户体验等都划归到该微服务设计者需要考虑的范围内。如图2所示。
2 自动化测试框架探索
目前常见的微服务设计都是会采用一些分布式服务框架,这些框架从通信协议上分为两种:公共标准的HTTP协议和基于私有的RPC调用协议。公共标准的HTTP协议有一些成熟的自动化测试工具可以使用,本文主要介绍使用RobotFramework工具设计实现的基于HTTP接口的微服务自动化测试框架。
2.1 基于Robot Framework的自动化框架设计
Robot Framework(以下简称RF)最初是由 Nokia Networks 公司开发的一个开源自动化测试框架,框架基于 Python语言实现,包含丰富的测试工具及测试库,同时具有很强的扩展性。RF框架通过集成不同的测试工具,可以进行各种自动化测试。微服务HTTP接口的测试,就是采用了RF内置的RequestsLibrary库中,Post Request、Get Request等方法进行进一步设计和封装。封装时,为了适用于普遍的HTTP接口,将微服务接口IP,URL地址,POST方法传递的报文,HTTP报文header,以及身份验证等信息作为参数开放。POST类型接口封装的关键字示例如图3所示。
图3:POST类型的HTTP接口调用封装
图4:用例中使用此关键字
在组织自动化用例时,采用数据与关键字分离的策略。将使用到的参数和报文体放在参数文件中,在用例中引用此参数文件获取参数值,用例中不展示参数正文,只见参数名称。这样组织用例的好处在于,只需要维护一份参数文件,如果接口定义或报文正文有变化,可以在文件中直接修改即可,无需大量修改用例。“&{params}”“&{interface}”都是字典类型的数据存储方式,可存储多个IP、URL链接等;${data}是定义在参数文件中的报文正文。按照这种思路封装关键字和组织自动化用例,用例步骤基本都固定,便于测试人员大规模构建用例。用例如图4所示。
2.2 自动化测试中的Mock思想
由于微服务架构中彼此服务之间是独立的,可自行组织开发、测试、上线等活动,但是彼此之间又存在通信调用关系。一个微服务接口开发过程中,某些功能的测试可能需要与其他服务通信,但其他服务可能不具备测试条件,所以微服务测试中需要用到Mock的思想。Mock是指在测试中,测试系统通过构造一系列符合预定义规则的模拟对象(Mock Object)来与被测试单元进行交互,从而判断被测试单元在正常逻辑,异常逻辑或压力情况下能够正常工作,返回预期的输出结果。Mock的使用需要配合一些已有工具,定义被调用方的模拟服务名、URL等,再配置相应的匹配规则和返回数据即可。Mock规则定义需要注意的是,不同规则需要设计唯一的关键字,当报文中具有这一关键字时会匹配到这个规则对应的返回数据,如关键字不唯一则会出现不同报文都返回同一数据的情况,造成测试结果的失真。Mock使用时需要在被测服务内部,配置模拟对象信息,在调用时,只要发送报文匹配到了Mock中的规则,即可获取到返回报文,达到忽略其他服务真实情况即可完成测试的目的,便于自动化测试用例的顺利执行。
3 结束语
本文在对现行通用的软件系统微服务架构学习的基础上,基于RobotFramework工具设计了用于微服务测试的自动化测试框架,并结合Mock测试思想,在微服务互相调用时采用了模拟报文返回的方式,使得自动化测试能独立执行,不受外部服务干扰,提高了测试效率。目前此自动化框架已经用于基于HTTP接口的微服务测试中,为功能的快速迭代起到了保障作用。