一、接口测试

接口测试详细介绍:接口测试基础(考虑到文章篇幅,下面接口测试只摘取该文中一部分,想了解详细内容可以跳转到该文章~)

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

1. 接口介绍

1.1 什么是接口?

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

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

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

1.2 软件为什么需要接口?

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

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

2.1 常见数据格式

  1. json 格式(最常用)

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

    • 常见返回数据

      1
      2
      3
      4
      5
      6
      7
      <html>
      <title></title>
      <body>
      <error_code>0</error_code>
      ...
      </body>
      </html>
  3. xml 格式

    • 常见返回数据

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

2.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"
}
]
}

3. 接口测试

3.1 什么是接口测试?

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

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

3.2 为什么要做接口测试?

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

简单的接口调用视图

3.3 如何开展接口测试?

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

3.4 接口测试分类

  1. 按测试粒度方面

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

    • 功能测试:单接口功能测试、多接口的业务场景
    • 性能测试:并发、大数据量等
    • 安全测试:认证、数据加密、脱敏、SQL 注入等

需求质量 代码质量 测试质量 发布质量
- 需求 Bug 数
- 需求打回次数
- 圈复杂度
- 类内聚度
- 构建成功率
- 测试覆盖率
- 漏测率
- CI 拦截问题数
- 发布成功率
- 发布回滚率
- 发布失败恢复时长

4. 接口测试协议

4.1 常见协议

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

4.2 什么是 Http 协议?

http 是超文本传输协议,主要用于浏览器和服务器之间数据的交互,其中交互有两个部分:

  1. 请求
    • GET,POST,PUT,DELETE
    • 请求报文格式:
text
1
2
3
  请求行     {     请求方法(get/post等)+     URL     +     协议版本号     }     
+ 头部 { 按照规范,根据自己需要来选择性添加 }
+ 包体 { 即数据内容,post请求时,这部分才有数据;get请求时,数据附在URL参数里,格式为【URL?参数名=参数值】 }
  1. 响应
    • 1XX 提示信息,2XX 成功,3XX 重定向(跳转不传值),4XX 客户端错误,5XX 服务端错误
    • 响应报文格式:
text
1
2
3
  状态行     {     协议版本号     +     状态码     +     状态码说明     }     
+ 头部 { 按照规范,根据自己需要来选择性添加 }
+ 包体 { 一般为服务端返回给客户端的数据 }

4.3 常见的请求头

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

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

  1. 拿到 api 接口文档,熟悉接口的业务、接口地址、鉴权、出入参数和错误码等
  2. 编写接口用例及评审,思路如下:
    • 正例:输入正常的入参,查看接口是否返回成功
    • 反例:
      • 鉴权反例:鉴权为空、鉴权码错误、鉴权码已过期
      • 参数反对:参数为空、参数类型异常、参数长度异常
      • 错误码覆盖:根据业务而定
      • 其它场景:接口黑名单、接口调用次数限制、分页场景
  3. 使用 Postman 接口测试工具执行接口测试
  4. Postman + Newman + Jenkins 实现持续集成,并输出接口测试报告和发送邮件

二、Postman 基础

1. 接口测试工具以及 Postman 介绍

接口测试工具:postman、jmeter、soupui、apipost、fiddler、charles

下载地址:https://www.postman.com/

2. 界面页签介绍

2.1 请求页签

  • Params:GET 请求传参

  • Authorization:鉴权

  • Headers: 请求头

  • Body:POST 请求传参

    • none:没有参数
    • form-data:既可以传键值对参数,也可以传文件
    • x-www-form-urlencoded:只能传键值对参数
    • raw:Text、JavaScript、JSON、HTML、XML 等格式皆能传递
    • binary:把文件以二进制的方式传参

  • Pre-request Script:请求之前的脚本

  • Tests:请求之后的断言
    官方将 Tests 重命名为 post-response,并与 pre-requests 一起聚合在 Scripts 选项卡里面。因此,如果你的 Postman 中没有找到 Tests 不要慌张,下面涉及到 Tests 的代码放到 Scripts 选项中的 Post-response 里,运行的效果是一样的。

  • Settings:对请求的一些设置

  • cookies:用于管理 cookie 的信息

2.2 响应页签

  • Body:接口返回的数据

    • Pretty:以 JSON、XML、HTML、Text、Auto 不同的格式查看返回的数据
    • Raw:以文本的方式查看返回的数据
    • PreView:以网页的方式查看返回的数据
  • Cookies:响应的 Cookie 信息

  • Headers:响应头

  • Test Results:断言的结果

  • 接口返回状态:

    • 200:状态码

    • OK:状态信息

    • 672 ms:响应的时间

    • 3.3 KB:响应的字节数

GET 请求和 POST 请求的区别:
1. GET 请求一般是获取数据,POST 请求一般是提交数据
2. POST 请求比 GET 请求更安全
3. 本质区别是传参的方式不一样:
- GET 请求在地址后面以 ? 的方式传参,多个参数之间用 & 分隔
- POST 请求是在 body 以表单的方式传参

3. 环境变量和全局变量

一般情况下的请求:

现在我们可以通过创建环境来代替我们请求中常用的地址。

然后在请求页面选择环境,就可以使用我们刚才创建的环境变量了。

两者变量的区别:

  • 环境变量:环境变量就是全局变量,但是需要在接口里选择环境使用
  • 全局变量:全局变量是能够在任何接口里访问的变量,接口不用选择环境就能直接使用

获取环境变量和全局变量的方式:

4. 接口关联

现在有一个场景,我想调用查询飞书云文档统计信息的接口,但是需要该文档的 token 信息。因此我需要先调用获取文档 token 信息的接口,再将 token 信息传递到前一个接口中进行调用。

API 文档:

4.1 正常调用流程

获取文件夹中的文件清单:找到需要查询文件的 token 信息。

获取文件统计信息:传入指定文件的 token,获取该文件的统计信息。

4.2 使用 JSON 提取器

获取文件夹中的文件清单:我们可以在 Tests 中使用 JSON 提取器,从响应的结果中获取到文件的 token 值,然后将这个值设置成全局变量,在接口 2 中可以直接使用。

如果对获取的结果不确定的话,可以通过 console.log() 来打印出获取的信息。

获取文件统计信息:在这个接口中,我们就直接可以传入全局变量即可。

三、Postman 进阶

1. 内置动态参数以及自定义的动态参数

1.1 Postman 内置动态参数

  • :生成当前时间的时间戳
  • :生成 0-1000 之间的随机数
  • :生成随机的 GUID 字符串

假设现在有个接口功能是「创建标签」,但是这个标签名字需要我们传递,且名字不能重复使用。如果调用多次这个接口的话,每次都需要手动修改传入的标签名字确保不重复就很麻烦。

因此,可以引入动态参数的概念,通过使用 帮我们随机生成参数。

1.2 自定义动态参数

除了使用 Postman 内置的动态参数之外,还可以自定义动态参数,在 “Pre-request Script” 下可以通过自定义脚本来获取动态参数。

而在接口请求体中,直接使用脚本中设置的全局变量 times 即可。

2. 断言

“You can use post-response scripts in Postman to execute JavaScript after a request runs. By including code in the Post-response tab for a request, collection, or folder, you can write and validate tests. You can also use post-response scripts for debugging tests.”

官方将 Tests 重命名为 post-response,并与 pre-requests 一起聚合在 Scripts 选项卡里面。因此,如果你的 Postman 中没有找到 Tests 不要慌张,下面涉及到 Tests 的代码放到 Scripts 选项中的 Post-response 里,运行的效果是一样的。

常用的断言:

  • Status code: Code is 200 -> 检查返回的状态码是否为 200
  • Response body: Contains string -> 检查响应中包含指定字符串
  • Response body: Json value check -> 检查响应中的 json 值
  • Response body: is equal to a string -> 检查响应是否等于一个字符串
  • Response headers: Content-Type header check -> 检查是否包含 Content-Type 响应头
  • Response time is less than 200ms -> 检查请求耗时是否小于 200ms

断言结果通过

断言结果失败

在断言中获取全局变量的方式:

  1. pm globals.get("times")
  2. globals["times"]
  3. globals.times

全局断言:

3. 批量运行测试用例

运行后,可以看到每个接口运行的结果以及断言是否通过。

4. Mock Server

当后端接口还没有开发完成时,前端如果存在业务需要调用后端接口,则可以通过创建 mock server 的方式来模拟期望返回的响应数据。

第一步:默认情况下不会开启此功能,需要在左侧工作空间设置中打开 Mock servers 的功能模块。

第二步:创建一个新的 mock server,可以在这里输入自己期望的请求与响应。

创建成功后,在 Mock servers、Environments 和 Collections 模块下都能看到新创建的 server。

第三步:调用模拟的接口,可以根据需求调整响应返回的数据,从而达到测试目的。

cookie 是一小段文本,格式为 key=value,其鉴权的原理为:

  • 当客户端第一次访问服务器的时候,服务器会生成 cookie 的信息,并放在响应头的 set-cookie 里面返回给客户端。
  • 当客户端第 2-N 次访问服务器的时候,客户端就会在请求头的 cookie 中带上 cookie 信息,从而实现鉴权。

cookie 的分类:

  • 会话 cookie:保存在内存,当浏览器关闭之后就会自动清除。
  • 持久 cookie:保存在硬盘,浏览器关闭之后不会清除,只有当失效时间到了才会自动清除。

在新创建的接口请求头中,是默认不会带 cookie 的,因为此时还没有从服务器端获取到相关信息。

当接口请求一次之后,若服务端返回了 cookie,则在下一次请求时就会默认带上 cookie 的信息。

在接口的右上角也能查看并管理自动获取的 cookie 信息。