API接口测试的思考
文字较多,请耐心阅读,你会有不一样的收获。
API testing, a.k.a. Application Programming Interface testing 它是任何一个internet项目下非常重要的一项, 在前后端分离, Serverless 渐渐流行的当下, 不论是作为粘合表现层与业务层的所在, 还是作为系统性能的入口, 都是我们测试金字塔的重要的一层.
这篇日记不想去讨论接口测试的完全必要性, (比如提升效率, 持续集成等等)以及RESTful接口的规范等技术标准, 只想从我自己的角度谈谈我们应该从哪些角度, 方面来去测试接口.
在狭义的角度上指的是对应用程序接口的功能进行测试,
在广义的维度上是指集成测试中,通过调用API测试整体的功能来完成度,可靠性,安全性和性能.
所以我们所说的E2E测试与集成测试模糊的边界问题, 其实就是我们如何去从这两个维度来测试API. 区别在于我们如何处理接口的依赖而已, 狭义上我们的应用程序已经部署好了, 所以我们测试的是它的全功能, 广义上我们测的是接口的Controller, 所以我们需要借助Mock(MockMVC等) 来处理依赖进行测试.
但是不论是狭义还是广义, 对API的测试思路是一样的.
-
功能测试, 即接口按照预期需求正常工作的测试, 包括异常处理等. -
可靠性测试, 即确保接口在各设备下工作正常且没有异常. -
负载测试, 即在各方面的请求到来时接口能够及时响应. -
压力测试, 即接口在接到的请求超过一定预期后的表现. -
安全测试, 即请求接口时, 应确保请求具有适当的身份验证, 权限与访问控制. -
集成测试, 即两个以上的接口之间通信应适当, 正常, 且一个接口的改动不会造成其他接口的错误. -
可用性测试, 即接口具有友好的响应体来提供给第三方或前端调用.
接口测试(协议部分)
作为测试人员, 我们一定掌握了一些测试用例的设计方法和手段, 比如我们会用xmind来梳理状态流转, 比如我们用场景图法, 因果图, 正交表, 配对, 等价类, 边界值, 判定表, 等等来设计用例.
其实这些方法只是训练或者模式你思考测试的思路, 接口测试(这里指http接口), 既然我们测试http协议的接口, 那我们必须要熟悉http协议, 协议原理, 请求header, body, 响应的header, body, callback等等.
首先简要说一下http协议, HTTP是基于应用层的协议, HTTP是一个无状态的协议, 但是在互联网的产品形态中,一个用户登录系统成功后,需要记录下谁登录了这个系统,以及这个用户它其他的数据信息,这就需要很清楚的掌握COOKIE的请求流程,当然这中间有这么几点是需要清楚的知道的,分别是COOKIE的请求流程,SESSION的请求流程,TOKEN的请求流程,以及HTTPS的请求流程.
当然了还有我们经常被问到的请求方法,如GET,POST请求方法.
接下来就是Response的部分, 我们需要了解状态码, 2xx, 3xx, 4xx, 5xx等, 我们需要了解JSON, XML等
当然还有其他的协议, soap, dubbo, rpc.....
接口测试(用例的设计)
测试用例, 应该是从AC(验收准则)衍生而来, 每一个用例都应该对应有价值的需求点, 每个测试点都是基于业务形态来展开, 所以我们一开始可以粗略的把业务接口测试分为
接口的功能是否正确实现了
接口是否按照设计文档/接口文档来实现, 比如返回username 写成了userName
错误码测试, 这和下面的异常测试可以放到一起.
返回值内容, 格式, 类型都要正确, 保证调用方能够正确的解析.
json格式的测试, JsonSchema的验证以及如果我们接口需要传递json串的地方, 那我们就需要测试传递非json的情况
默认值测试, 比如有些接口的参数如count 默认20, 那么我们就需要去检查它是否按照默认值返回.
是否有逻辑业务依赖, 比如需要登录状态下调用, 那我们就需要考虑在登录与非登录状态下调用的情况
数据库的逻辑验证, 通过接口的调用实现对数据库的增删改查,需要我们去验证数据库是否也同步操作
第三方中间件的操作, 需要调用接口来验证中间件如redis,kafka,等的操作
异常测试, 很多时候测试覆盖率其实就在这里实现了, 不外乎两种
参数异常:
关键字参数, 将传递的参数写为开发语言的关键字进行测试
多参少参, 将传递参数不传或者多传一些其他关键字的参数进行测试
错误参数, 大小写转换/错误的参数 如果有嵌套的json格式的参数, 同样需要对前套内参数进行验证, 尤其对于update 的接口更需要这样的用例来验证develop对于参数的处理策略.
数据异常:
-
数据为空, 值传递空, null, ""等来测试 -
传递的body体为空, 或空json, 空字符串等 -
关键参数传递数据为空或不传递 -
边界值数据, 0,-1,或等于, 边界值-1 的数据 -
长度不一致的数据, 长度超限制的数据 -
错误数据, 包括类型错误, 如果有固定范围的数据需要传递不在范围的数据
安全测试: 基于简单的验证
敏感信息是否加密处理
必要参数是否后端也会校验, 比如付款金额等重要信息是一定需要后端进行校验的
接口是否防恶意请求(SQL注入)
cookie/token, 将cookie token 修改或者删除看是否返回相应的error code
header, 删除修改header中部分参数的值, 看是否返回相应的error code
是否增加了反爬虫的机制
是否增加了请求次数的限制
是否对timeout进行了限制
性能测试:
是否满足需求中的响应时间与吞吐量
业务场景测试形态下, 我们更注重考虑的是:正常的业务逻辑以及异常的程序逻辑判断
正常的状态机逻辑的流转
某个状态异常的情况下整个业务的状态
确保每个用例的独立性, 比如dataset这个资源, 有create/get/delete/update 接口, 那我们的每一个用例就需要有create和delete, 创建--执行--断言--清理, 一定是这样的一个流程
对于delete/update 非幂等性的接口, 我们需要进行二次调用, 比如在delete 一个dataset后, 我们需要再次调用delete, 来验证接口的幂等属性
-
场景图法 - 测试业务流的组合逻辑覆盖 1.1 使用事件流的图示方法来对基本流, 备选流 进行正常和异常的验证 -
因果判定表 – 测试用户操作流组合覆盖 2.1 操作关系:用户输入输出操作关系组合 -
等价边界值 – 测试数据流组合覆盖与数据校验 3.1 逻辑对象:页面业务数据字段 3.2 物理对象: 显性数据字段(页面上面对用户的业务字段)与隐性数据字段(接口中参数,数据表中非业务字段) 3.3研究关系:有效合法数据和无效非法数据
-
可理解性, 用例内容 given, when, then -
清晰性, 层次结构清晰, 上页的三层结构 -
有效性,可测试(SOLID, 单一职责/依赖倒置,环境setup,teardown)/开放封闭/隔离/替代 -
可重用 -
可调用 -
可重构
接口测试(原则)
不要相信用户, 不要相信文档, 不要相信任何参数和数据, 甚至不要相信返回值