接口 Interface是一种数据、信息互通的便捷实现方式,在日常生活中随处可见笔记本Usb接口、音视频接口,手机充电线接口等等。我们两个团队相互协作,为了便于管理和协调,通常会选接口人。在计算机系统中我们经常使用接口实现不同模块之间的功能调用,或者提供专门的接口服务方便方便他人调用实现自己的业务逻辑。所以从本质上来看,接口的作用就是将组织、系统的服务功能向外暴露,从而以最简洁的方式与外部互动,使得内部的细节很好的保护,即便内部逻辑有变动也不会影响服务的提供。
接下来我们一起探讨的是计算机应用的接口,梳理接口在开发、测试实践中的一些应用,有些面向对象的编程语言中会有Interface关键字来抽象方法,其他类使用这些方法就会继承和实现方法实体,比如Java语言通过extends继承接口,通过implements来实现接口定义的方法;有些编程语言没有interface关键字,但也会有自己的方式来实现类似的接口功能。对计算机应用程序来说使用接口能够方便功能模块之间的衔接调用从而实现一个完整的系统,在JAVA项目开发过程中一般会将代码分层处理,负责数据库操作的为DAO层;负责业务逻辑处理的为Service层;前后台交互控制为Controller层;这些层之间的方法调用一般会使用接口,比如Controller在调用Service方法时需要先实例化接口,再通过接口调用实现方法。这样的好处就是各层的职责界定清晰,分工协作。
我们常说前后端分离、微服务、服务网格等等,它们更多的是系统架构上的考量,在技术实现上会大量使用接口操作。前后端分离的目的也是降低系统的耦合度,前后端的数据交互是使用前端调用后端接口的方式实现,现在通常的做法是Ajax或REST方式,接口数据格式一般是使用JSON串。
微服务是将原来单体应用中的功能服务细颗粒度拆分,并将服务注册到注册中心以便其他服务通过接口的方式调用方法,为了有效的管理各接口会使用API接口网关;
应用程序编程接口API(Application Programming Interface)对于开发人员不陌生,在开发具体实践中会接触到很多种类的API接口,比如Webservice接口、REST接口、RPC接口、Socket接口等,每种接口类型使用的底层支撑技术不同,所面向应用的场景、适合解决的问题也不尽相同。Webservice通常是两个系统之间的远程方法调用,调用方一端知道远程被调用端的url地址,通过WSDL描述的XML文档查询要调用其上的哪个方法,最后通过SOAP协议传递方法需要的参数,从而实现两端数据交互。REST是目前比较常用的一种基于HTTP服务的接口,只要知道接口地址,在发起请求时带上参数和数据就能获取到期望的结果。RPC是远程过程调用(Remote
Procedure Call),属于进程间通信的范畴,不同机器上的应用可以通过RPC远程调用其上的方法,这里可以看到Webservice的处理过程中其实使用了RPC。Soket接口属于操作系统底层实现接口,使用sokect时一般会先建立长连接,然后传送数据进行业务逻辑处理,结束后需要关闭连接。比如我们常用的MQ,文件上传下载都会使用soket接口。
我们知道使用API的目的就是为了方便程序之间的协作,不需要了解服务提供方的源码程序逻辑就能实现数据交互。我们常看到好的API都非常简洁,一个设计和操作很复杂的API就已经不是好的API了,因此在API设计中需要遵循一些原则。
首先一个API功能应该单一、明确,通常不建议一个接口里包含多个功能操作,返回的数据应该采用特定的格式,比如XML、JSON格式等;
其次API功能应该彼此独立,不应该有功能点重叠的API,而且API应该尽可能穷举。
再者,API命名应清晰可理解,通过API名称或url地址就能知道API做什么的是比较好的 。
安全性也是API设计中比较关键的,特别是对外公开的接口通常都采用权限控制,比如采用
OAuth2.0认证,用户操作需要之前先获取Token,通过Token验证之后才允许获取数据。
另外在做API设计时,应该维护一套API文档且定期维护,特别是前后端分离,或者移动端应用跟后台系统交互时,如果没有API文档,双方交流就多了阻碍。
当然还有其他的一些设计原则,比如对API新旧版本的兼容等,很多原则需要在实际的开发实践中逐步探索。目前也有专门的插件或者工具来生成、维护管理接口文档,比如Swagger可以嵌入在代码中,通过在接口方法中增加注解@api,就可以将接口信息纳入到Swagger管理,项目运行时可以自动生成接口文档。
项目启动后,浏览器中访问http://localhost:8080/swagger-ui.html#/ 可展示各Controller中的接口列表,点开接口可查看详情及接口响应示例,点开POST请求还可输入参数进行测试、验证。
因为REST和RPC是目前常用的API,因此再多说一点。首先需要说明的是REST和RPC都属于架构设计方式,我们知道REST(
Representational State Transfer:
表述性状态传递),
是一种软件架构风格,上面说过RPC是远程过程调用,他们都提供了相应的API方便我们使用。
RESTAPI使用的是HTTP请求,它常用的操作中主要包括POST、GET、PUT、DELETE等,在Spring、Flask、Django等框架中都很好的支持RESTAPI方式,在前后端分离的架构中,我们可以使用RESTAPI的方式调用后台服务以获取数据或操作数据,在一些大型互联网公司,REST也还不能满足特定的需求,比如想同时获取微信账号的个人信息、个人图片、所有朋友的名称、朋友图片和朋友圈等信息,如果使用REST,每个数据都需要调用一次接口,而且想要获取完整想要的哪些字段,必须先要将REST获取到的数据暂存再聚合再一起,而同时有很多不关心的数据,比如朋友添加的时间。这样GraphQL就在REST的基础上演化出来了,它是一个树状结构的API查询语言,可以灵活的查询到想要的结果,前提是需要准备好schema和type,并定义Resolver解析函数,之后就可以编写query查询期望的内容。比如对于操作 通过API接口操作文章。
对于REST:
GET /api/v1/articles/
GET /api/v1/article/:id/
POST /api/v1/article/
DELETE /api/v1/article/:id/
PATCH /api/v1/article/:id/
对于GraphQL:
query {
articles(): [Article!]!
article(id: Int): Article!
}
mutation {
createArticle(): Article!
updateArticle(id: Int): Article!
deleteArticle(id: Int): Article!
}
两者的区别为了便于理解,REST可以比作是单条sql语句查询数据库,而GraphQL则是聚合查询,效率和操作上会有明显的差别。
目前流行的开源 RPC 框架主要有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。其中Dubbo和gRPC最广为人知,其中Dubbo是作为一个微服务架构,有注册中心、服务提供方、服务消费方等,消费方要消费先到注册中心获取服务列表,然后通过RPC方式远程调用服务提供方进行消费。可以简单理解gRPC是普通RPC的升级版,主要是应对接口定义严格且性能要求较高的场景。
我们设计好了接口或者拿到别人写的接口,如何进行验证呢?接下来就具体说一下接口测试方面的事情。大多时间跟功能测试中的黑盒一样,在测试接口时也是不知道接口的内部实现,但知道请求什么、输入什么期望得到什么返回结果,期望以此验证系统逻辑。
验证接口通常不涉及到具体的界面,这样测试反而更有针对性也更专注,因此首先要知道都有哪些接口,每个接口是做什么的,返回数据包含什么,开发人员提供一份清晰的接口文档是非常必要的,有问题交流起来也很方便。其次根据实际情况选择手工测试还是考虑自动化,如果接口量很少也不需要多轮次验证,手工测试就可以;如果接口量大或者需要接口回归测试,搭建通用的接口自动化框架是有必要的。相对于其他类型的测试工作,接口自动化反而是自动化测试中
实施难度最小的部分。
最后要考虑接口测试的具体事实,是借助于已有的工具,还是自己编写一套则需要根据实际情况选择。
接下来介绍常用的接口测试工具。
在接口测试中,POSTMAN是一款很好用的工具,输入url和key/value 格式的headers以及请求数据,选择POST请求方式就能提交数据,成功和失败都会响应。也可以GET、DELETE等请求方式。
能够根据需要,生成代码。也就是说在POSTMAN界面手工测试的的内容,可以生成我们期望的代码段,代码编程语言可以选择,有了这些基础的代码可以通过自己写程序请求访问。
上面这些还只是一些基础的使用,它也 提供一些高级的用法,比如建立测试集合,将不同的接口链接起来。还有其他一些高级功能,不过高级的功能收费。
跟POSTMAN类似的一套开源免费的接口测试工具,除了支持常规的http请求、RESTAPI,它还支持WebSoket、MQTT、GraphQL等类型接口验证,还可以根据Collectios生成接口文档。这款工具的功能还在不断增加,是一款不错的接口调试工具。
Selenium是一款功能自动化工具,跟惠普的QTP类似,WebDriver可以跟浏览器结合做界面自动化测试,当然也可以跟python、Java等一起做接口自动化,不过对编码能力有要求。如果要搭建一套完整的自动化测试框架,还可以跟Jenkins等工具结合构建体系化的自动化测试。
Jmeter是一款被公知的性能测试工具,它也很适合做接口测试,甚至用它来做接口自动化。
如果对于前端向后台请求不知道接口都有哪些,特别是在没有公开API文档的情况下,想自己梳理出接口和接口请求,可以使用Fiddler拦截,当然也可以使用Chrome、Firefox等浏览器自带的开发者工具查看各个请求,但这样做是比较费劲的。
我们在实际的测试过程中,肯定会跟接口打交道,只不过有时有专门做接口测试,或者用功能测试代替了接口测试。接口测试和功能测试经常被认为测试内容有重叠,功能测试可以替代接口测试。而我想说接口测试和功能测试是两个角度和思路,虽然功能测试也会覆盖到各个接口,但两者关注点不一样,采用的测试方法和策略不同,接口关注的更多是接口数据返回是不是符合业务逻辑的预期,能更早的暴露出问题;而功能测试则会关注系统整体对外提供的服务是否满足预期,一个功能点可能包含多个接口,而且还会涉及到前端的功能。接口测试具体用哪套工具,其实工具没有严格意义上的好与坏,根据项目实际情况
和个人的习惯来选择。
本篇主要介绍接口的作用和常见的使用,接口是能够便捷的与外部沟通协作的连接单元。在软件系统开发中使用接口可以有效降低程序之间的耦合度,使程序逻辑更清晰。在设计API接口时也应遵循一些基本的原则,从而让我们的API更好的被理解和使用。粗略介绍了RESTAPI和RPC的特点和常见的应用场景,这两种类型的API随着使用场景的丰富在不断的演化。在接口设计中可以使用类似于Swagger这样的第三方工具方便生成接口文档。接口测试时也可以根据实际需求选择适合的工具,当然更重要的是我们在测试过程中的一些想法、思路,有了想法之后再结合工具才有可能到达我们的目的。