接口测试的本质:测试接口是否能够正常的进行数据交互、权限控制以及异常管理。

1. 测试策略

  1. 传统软件产品测试策略
    • 测试周期长
    • 强调文档驱动
    • 注重质量保障
    • 较少考虑快速迭代
  2. 互联网产品测试策略
    • 快速迭代
    • 用户体验至上
    • 大数据和性能测试
    • 持续监控和反馈

传统软件产品的金字塔测试策略

互联网产品的菱形测试策略

Tips:
UI 方面的功能测试属于黑盒测试,单元测试属于白盒测试,而 API 接口测试则属于灰盒测试。

因此,互联网产品测试策略大概可以总结为如下几点:

  • 以中间层的 API 测试为重点做全面的测试。
  • 轻量级的 GUI 测试,只覆盖最核心直接影响主营业务流程的 E2E 场景。
  • 最上层的 GUI 测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题。
  • 单元测试只对那些相对稳定并且核心的服务和模块开展全面的单元测试,而应用层或者上层业务只会做少量的单元测试。

2. 接口介绍

2.1 什么是接口?

接口的本质,其实就是一种契约,遵循这样一种形式:在发开前期,我们约定接口会接收什么数据;在处理完成后,它又会返回什么数据。

  1. 硬件:电脑 - USB、投影机等
    • 用于数据传输
  2. 软件:统称 API(application program interface)
    • 通过调用接口来实现例如微信提现和充值、支付宝支付等功能
    • 接口的调用可能需要鉴权,鉴权码一般称为 token/key/appkey
  3. 接口包含了内部接口和外部接口
    • 内部接口
      • 内部接口只提供给内部系统使用,例如预算系统(只需要测试正例即可)
      • 内部接口提供给外部系统使用(测试必须非常全面,正例、异常和权限控制等场景都需要覆盖)
    • 外部接口
      • 开发系统调用外部的接口,例如微信、支付宝等对外接口(只需要测试正例即可)

总结:接口就是软件提供给外部的一种服务,用于数据的传输。

2.2 软件为什么需要接口?

因为接口能够让内部的数据被外部进行修改。比如,微信支付后银行卡中的余额需要修改,这时候就需要银行提供对外的接口,用于支付后对银行卡金额数据的修改。

3. 接口返回数据和 JSON 详解

3.1 常见数据格式

  1. json 格式(最常用) 常见返回数据:
    • error_code:错误码,0 代表成功
    • msg:对错误码的中文说明
    • data:真正返回的数据
1
{error_code:0, mas:"提现成功", data:[]}
  1. html 格式 常见返回数据:

    1
    2
    3
    4
    5
    6
    7
    <html>
    <title></title>
    <body>
    <error_code>0</error_code>
    ...
    </body>
    </html>
  2. xml 格式 常见返回数据:

    1
    2
    3
    4
    <?xml?version="1.0" encoding="utf-8">
    <error_code>0</error_code>
    ...
    </xml>

3.2 JSON 详解

推荐格式化工具:https://github.com/zxlie/FeHelper

关于 JSON:

  1. JSON 就是一种数据类型
  2. JSON 由两种数据组成:
    • Map 对象/键值对:{key:value, key:value}
    • 数组:[value1, value2, value3]
  3. 合法的 JSON 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{"a": 1,"b": [1, 2, 3]}

[1, 2, "3", {"a": 4}]

3.14

"plain_text"

{
"prople":[
{
"firstName": "Brett",
"lastName": "McLaughlin"
},
{
"firstName": "Jason",
"lastName": "Hunter"
}
]
}

4. 接口测试介绍

4.1 什么是接口测试?

接口测试其实就是模拟调用方,通过接口通信来检测接口的正确性和容错性。

接口测试也是功能测试,和 UI 界面测试不同的地方,仅仅是和我们交互的,不再是开发工程师设计的界面,而是测试工具或者代码。

4.2 为什么要做接口测试?

  1. 现在很多系统都是前后端分离,开发进度可能会不一样,不需要等前后端都开发完再介入测试,而是在接口开发完后就可以开始介入测试了。
    • 如果前端开发好,但后端还没有开发好,那么可以 mock 数据进行测试。
    • 如果后端开发好,但前端还没开发好,那么可以直接调用后端接口进行测试。
  2. 基于安全考虑,前端有些验证是很容易被绕过去从而直接调用接口,因此要针对此场景进行测试。
  3. 测试推崇的是测试左移,而接口测试可以尽早的介入测试。

Tips:
测试要尽早的介入这句话不仅仅只是指 QA 这个角色要尽早介入,而是指测试这个活动要尽早介入到质量保障当中,也可以是研发通过某些手段在开发阶段,即问题出现的早期就能被发现。

简单的接口调用视图

另外,从个人方面来说来说作为一名测试工程师,掌握接口测试,并能熟练完成接口测试,无疑对你在求职时和作中都有很多好处,比如:

  • 增加自己的技能,在找工作时获得更多机会。
  • 通过接口自动化完成接口回归测试,让自己的工作更轻松、更高效。
  • 通过持续集成平台调用接口自动化测试,为流水线提供质量保障方法和手段,赋能研发过程。

4.3 接口测试分类

  1. 按测试粒度方面
    • 单接口验证:验证接口参数、返回值是否正确,更多只是为了验证接口是否能用
    • 业务场景逻辑验证:以用户场景、业务场景为基础,验证接口与接口之间参数传递及业务流程能不能使用,更多是为了验证业务接口链路正不正常(这个是接口测试最核心的价值)
    • 异常验证:验证参数异常、逻辑异常等情况,接口是否能处理并给出友好的错误提示信息。
  2. 按测试类型方面
    • 功能测试:单接口功能测试、多接口的业务场景
    • 性能测试:并发、大数据量等
    • 安全测试:认证、数据加密、脱敏、SQL 注入等

4.4 接口断言设计

  1. 请求协议的连通性,2XX,HTTP,判断状态码是不是 200
  2. 接口业务的状态码是否正确
  3. 验证返回的数据接口是否和事先定义的一致
  4. 验证数据的值是否符合预期
  5. 验证异常

4.5 接口测试 / 自动化测试误区

  1. 所有的接口都可以做接口测试,但并不是所有接口都适合做接口测试
  2. 接口测试 / 自动化测试它解决的是效率问题,而不是单纯为了去发现 BUG
  3. 接口测试 / 自动化测试是可以提升效率,但并不是立刻见效,这是一个长期的过程,从 0 到 1 的过程所花费的时间可能比单独手工测试还要多,但从长期来看一旦搭建起来,带来的成效是十分可观的

4.6 接口测试效果度量

  • 线上质量
服务端 移动端
1. 流量
2. 故障 / 缺陷
3. 性能
4. 饱和度
5. 线上告警
1. 可靠性
2. 性能效率
3. 兼容性
4. 易用性
5. 可维护性
6. 安全性
  • 过程质量
需求质量 代码质量 测试质量 发布质量
1. 需求 Bug 数
2. 需求打回次数
1. 圈复杂度
2. 类内聚度
3. 构建成功率
4. 千行代码 Bug 率
5. PR decline 率
1. 测试覆盖率
2. 漏测率
3. CI 拦截问题数
4. 缺陷分析
5. 自动化覆盖率
1. 发布成功率
2. 发布回滚率
3. 发布失败恢复时

5. 接口测试协议

5.1 常见协议

  1. WebService 协议
  2. Dubbo 协议
    • 接口地址以 Dubbo 开头
    • 适用于少量数据的传输,高并发场景;但不适用于传输大文件、视频等数据
  3. HTTP 协议(最常用)
    • 接口地址以 HTTP 开头
    • HTTPS = HTTP + SSL 安全传输协议
    • HTTP 端口为 80,HTTPS 端口为 443

5.2 什么是 RESTful 规则?

RESTful 是一种网络应用程序的设计风格和开发方式,基于 HTTP 协议可以使用 XML 格式定义或 JSON 格式定义,适用于移动互联网厂商作为业务使能接口的场景。通过 RESTful API 可以对互联网资源进行操作,所谓 “ 资源 “,就是网络上的一个实体,或者说是网络上的一个具体信息。

示例:

  • GET /order/1:返回订单编号为 1 的订单
  • POST /orders:增加一个订单
  • DELETE /orders/1:删除一个订单编号为 1 的订单
  • PUT /orders/1:更新订单编号为 1 的订单

URL 和 URI 的区别

  • URI = Universal Resource Identifier 统一资源标志符,是一个更通用的概念,用于标识一个资源。它可以是一个名称、一个地址或者任何可以唯一标识资源的字符串。URI 是一种抽象的标识符,不涉及如何访问资源的具体方式。
  • URL = Universal Resource Locator 统一资源定位符,是 URI 的一个具体实现,它不仅标识了资源,还指定了如何访问这个资源的具体方式,通常包括协议(如 HTTP、HTTPS、FTP 等)、服务器地址、端口号、路径和查询参数等。
  • URN = Universal Resource Name 统一资源名称,它不提供资源的位置信息,而是通过一个持久的、独立于位置的名称来标识资源。

URI 包括 URL 和 URN 两个类别,URL 是 URI 的子集,URL 一定可以标识出一个唯一的资源,所以 URL 一定是 URI;而 URI 包括范围更广,因此不一定是 URL。

URN 由于可能会存在同名的情况,因此不能等于 URI,所以目前一般都直接用 URL 来标识唯一的资源(前提是要按照标准规范进行设定)。

5.3 什么是 HTTP 协议?

HTTP 是超文本传输协议,主要用于浏览器和服务器之间数据的交互

  • 请求体
    • 请求方法: GET,POST,PUT,DELETE
      请求报文格式:
1
2
3
4
5

请求行 { 请求方法(get/post等)+ URL + 协议版本号 }
+ 头部 { 按照规范,根据自己需要来选择性添加 }
+ 包体 { 即数据内容,post请求时,这部分才有数据;get请求时,数据附在URL参数里,格式为【URL?参数名=参数值】 }

  • 响应体
    • 响应状态码: 1XX 提示信息,2XX 成功,3XX 重定向(跳转不传值),4XX 客户端错误,5XX 服务端错误
      响应报文格式:
text
1
2
3
状态行     {     协议版本号     +     状态码     +     状态码说明     }     
+ 头部 { 按照规范,根据自己需要来选择性添加 }
+ 包体 { 一般为服务端返回给客户端的数据 }

HTTP 请求中 params 与 data 的区别

requests 模块发送请求有 params、data 两种携带参数的方法。

  • params
    • params 常用在 GET、HEAD 请求方法中,通常用于向服务器传递查询信息,以获取特定资源或执行特定操作。
    • 例如,在一个搜索功能中,可以使用 params 来传递搜索关键词、页码、每页显示的数量等参数。
    • 这些参数会附加在 URL 的末尾,以 ?key=value&another_key=another_value 的形式呈现。
  • data
    • data 常用在 POST、PUT、PATCH 等请求方法中,通常用于在请求中向服务器发送数据。
    • 可以发送各种类型的数据,如表单数据、JSON 数据等。数据被包含在请求体中,而不是在 URL 中。
    • 例如,当提交一个表单或创建一个新的资源时,可以使用 data 来发送表单数据或 JSON 格式的资源数据。

在 requests 库中,两者使用方式:

1
2
3
4
5
6
7
8
import requests

# 使用 params 发送 GET 请求
response1 = requests.get('https://example.com/api/search', params={'keyword': 'example', 'page': 1})

# 使用 data 发送 POST 请求
data = {'name': 'John', 'age': 30}
response2 = requests.post('https://example.com/api/create', data=data)

HTTP 与 HTTPS 的区别

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

5.4 常见的请求头

  • Host:请求的主机地址
  • Connection:连接方式
  • Accept:客户端接收到的数据格式
  • X-Requested-With:异步请求
  • User-Agent:客户端的用户类型
  • Referer:来源
  • Cookie:cookie 信息
  • Content-Tpye:请求内容的格式

6. 如何开展接口测试?

6.1 接口测试基本流程

Tips:

无论你引入了一个多么强大的自动化测试框架,你首先都要会用最原始的方式完成这件事情:关注输入和预期是否一致、接口内部实现的处理逻辑是否合理、是否健壮。

通常来讲,无论采用什么 API 测试工具,API 测试的基本步骤主要包括以下三大步骤:

  • 准备测试数据(这是可选步骤,不一定所有 API 测试都需要要这一步)
  • 通过 API 测试工具,发起对被测 API 的 request
  • 验证返回结果的 response

理想情况,提测后,开展测试的必要输入内容:

  • 产品需求: 描述了系统的业务逻辑,通过这个文档,你才能知道怎么来设计测试用例。
  • 原型设计: 会更加直观地告诉你系统的使用逻辑,这对测试用例的设计、对系统的前期认知都是有辅助作用的。
  • 接口文档: 详细地描述了后端接口的访问方式和参数说明,使用这个输入项才能开展接口测试用例的设计、测试脚本的准备和测试数据的构建。
  • 单元测试脚本: 是保障提测质量的必要环节,是研发工程师自测的一个有效手段,可以保障提测项目的提测质量。

现实却往往并不总如人意,我相信你多少也遇见过下面这些情况:

  • 根据产品经理的一句话需求,开发工程师便开始任意发挥,” 所见系统即需求 “ 的情况普遍存在,这就更别说后续的单元测试和接口文档了。
  • 开发工程师从来不写单元测试脚本,提测项目质量无法保障,接口文档更无从谈起,你不知道如何开始完成接口测试。
  • 你在拿到提测项目后,从部署测试环境到开始测试,一直都是摸黑前进,由于接口测试没有充分的输入条件,只能从 UI 层开始测试,结果导致交付质量大打折扣。

6.2 三步闭环法

但这些事情的核心还是取决于 QA 人员的自驱力,可以通过如下的三步闭环法快速了解接口的信息:

  • 借助一些工具的辅助来完成接口分析。
  • 通过工具截获一些接口信息。
  • 通过分析接口的访问方式、参数等信息整理出一些问题,和研发工程师沟通这些问题,将一些不知道的参数含义、参数取值范围等问题问清楚。

  1. 工具辅助

    抓包工具推荐:Fiddler 或 Charles

    Fiddler 既支持 Windows 操作系统,也支持 MacOS 操作系统,但是在 MacOs 上的版本并不好用,这是因为 Fiddler 使用了 .Net 开发。如果你是一个 MacOS 深度用户,那么推荐两款工具,一款是 Charles,另外一款是 mitmproxy。

  2. 分析问题

    • 请求体: 重点关注请求方法、请求 URL、请求参数、客户端接收内容类型 Accept、Cookie 等。
    • 响应体: 看请求的 Response 响应信息、响应体结构,重点关注接口返回值有哪些内容,该接口的返回值是否是另外接口的入参,即串联业务逻辑上下文的参数。

    通过上面的请求分析,你就可以自己绘制类似如下的表格,通过颜色标注哪些是自己已知内容、哪些是未知信息。

  3. 询问解惑

    针对每一个参数,你都要从下面的几点详细询问,并保证你已经真的理解了这些内容。

    • 参数的含义以及来源
    • 参数的作用域
    • 返回值的含义

6.3 业务流程多接口串行分析

  1. 通常一个测试的业务逻辑是由多个接口的串行完成的,而多个接口的串行逻辑是由业务逻辑规定的。因此多个接口之间并不是随意组合的,而是按照业务逻辑、通过数据传递来完成的。
  2. 要想使用接口测试完成业务逻辑,你就要制作一个流程中所有接口的接口信息表。同时还要理清每一个流程的数据流程,数据流程驱动了业务流处理,这样才能开始业务逻辑的接口测试。

6.4 企业接口测试的流程和方案

  1. 拿到 api 接口文档,熟悉接口的业务、接口地址、鉴权、出入参数和错误码等

  2. 编写接口用例及评审,思路如下:

    • 正例:输入正常的入参,查看接口是否返回成功
    • 反例:
      • 鉴权反例:鉴权为空、鉴权码错误、鉴权码已过期
      • 参数反对:参数为空、参数类型异常、参数长度异常
      • 错误码覆盖:根据业务而定
      • 其它场景:接口黑名单、接口调用次数限制、分页场景
  3. 使用 Postman 接口测试工具执行接口测试。到目前为止,你还处在手动测试的阶段,虽然已经和以前基于界面的业务测经有了很大区别,但是距离自动化的接口测试还有有一定的差距

  4. 因此我们可以通过 Postman + Newman + Jenkins 实现持续集成,并输出接口测试报告和发送邮件