vlambda博客
学习文章列表

API接口测试的思考

文字较多,请耐心阅读,你会有不一样的收获

API testing, a.k.a. Application Programming Interface testing 它是任何一个internet项目下非常重要的一项, 在前后端分离, Serverless 渐渐流行的当下, 不论是作为粘合表现层与业务层的所在, 还是作为系统性能的入口, 都是我们测试金字塔的重要的一层.

API接口测试的思考

这篇日记不想去讨论接口测试的完全必要性, (比如提升效率, 持续集成等等)以及RESTful接口的规范等技术标准, 只想从我自己的角度谈谈我们应该从哪些角度, 方面来去测试接口.

接口测试的维度与分类
    API的测试是软件测试的一种测试模式,它包含了 两个维度:
  • 在狭义的角度上指的是对应用程序接口的功能进行测试,

  • 在广义的维度上是指集成测试中,通过调用API测试整体的功能来完成度,可靠性,安全性和性能.

所以我们所说的E2E测试与集成测试模糊的边界问题, 其实就是我们如何去从这两个维度来测试API. 区别在于我们如何处理接口的依赖而已, 狭义上我们的应用程序已经部署好了, 所以我们测试的是它的全功能, 广义上我们测的是接口的Controller, 所以我们需要借助Mock(MockMVC等) 来处理依赖进行测试.

但是不论是狭义还是广义, 对API的测试思路是一样的.


    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.1 使用事件流的图示方法来对基本流, 备选流 进行正常和异常的验证
  2. 因果判定表 – 测试用户操作流组合覆盖
    2.1 操作关系:用户输入输出操作关系组合
  3. 等价边界值 – 测试数据流组合覆盖与数据校验
    3.1 逻辑对象:页面业务数据字段
    3.2 物理对象: 显性数据字段(页面上面对用户的业务字段)与隐性数据字段(接口中参数,数据表中非业务字段)
    3.3研究关系:有效合法数据和无效非法数据

接口用例设计原则
  • 可理解性, 用例内容 given, when, then
  • 清晰性, 层次结构清晰, 上页的三层结构
  • 有效性,可测试(SOLID, 单一职责/依赖倒置,环境setup,teardown)/开放封闭/隔离/替代
  • 可重用
  • 可调用
  • 可重构


接口测试(原则)

不要相信用户, 不要相信文档, 不要相信任何参数和数据, 甚至不要相信返回值