接口自动化测试实战

师资培训

霍格沃兹测试开发学社

ceshiren.com

大纲

  • 行业对于接口测试的需求
  • 接口测试的学习体系/课程设计
  • 接口自动化测试的学习体系/课程设计
  • 接口自动化测试实战练习

接口测试课程体系

霍格沃兹测试开发学社

ceshiren.com

接口测试招聘需求

接口测试概念

  • 接口:不同的系统之间相互连接的部分,是一个传递数据的通道
  • 接口测试:检查数据的交换、传递和控制管理过程
  • 使用场景:针对于前后端分离的产品(基本上市面上的绝大部分产品)

接口测试的价值

  • 传统的测试方法成本急剧上升
  • 测试效率下降

名企的接口文档

接口测试与功能测试的对比

接口测试工具类型

测试类型 工具
接口数据分析 Charles、Fiddler、谷歌开发者工具
弱网测试 Charles、Fiddler
性能测试 JMeter
安全测试 owasp
功能测试 Postman
自动化测试 Python+Request、Java+RestAssured
性能测试 JMeter
Mock技术 Charles、Python+Requests、Java+RestAssured

接口测试技术需求

级别 年限 技术需求
初级 应届生 掌握协议相关的计算机网络知识
掌握基本的http协议接口的测试
掌握常用工具的使用:Postman、Charles、Fiddler
中级 1~3年 掌握http自动化测试技术,python+requests、java+rest-assured
高级 3~5年 能优化接口自动化测试脚本,并了解其他的接口测试技能,比如mock、性能测试
资深 5年以上 能二次定制常用的接口测试框架,并掌握其他的接口测试技能,比如mock、安全、性能
专家 5年以上 能独立开发可用的接口测试框架,类似HttpRunner

知识体系

https://course.ceba.ceshiren.com/courses/theme/专题课/接口自动化测试/

课程设计

  • 由浅入深
  • 根据课时的不同选择不同的难度
  • 实践和理论结合

理论课-接口测试初级

  • 掌握接口测试的知识体系与学习路线
  • 掌握常用接口测试工具postman
  • 掌握常用抓包工具charles与fiddler
  • 结合知名产品实现接口测试实战练习

接口测试理论课(8~12个课时)

形式 章节 课时
知识点 接口测试价值与体系 0.5课时
知识点 常见的接口协议与简单抓包 0.5课时
知识点 接口测试用例编写 1 课时
知识点 postman 基础使用 1~2个课时
知识点 抓包工具 charles 1~2个课时
知识点 抓包工具 fiddler(与charles二选一) 1个课时
知识点 抓包工具证书配置 1个课时
知识点 App 接口数据抓包 1~2个课时
知识点 代理工具 弱网 mock 使用 2个课时

接口测试实践课(6~12个课时)

  • 课时长短主要根据被测产品以及需求的复杂度
形式 章节 课时
实战 抓包分析实战练习 1~2 课时
实战 接口测试实战练习 3~6课时
实战 mock实战练习 2~4课时

接口自动化测试

接口自动化测试与UI自动化测试对比

接口自动化测试场景

web自动化测试 接口自动化测试
成本 ⭐️⭐️⭐️ ⭐️
测试效率 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
用例编写效率 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
稳定性 ⭐️⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
自动化回归测试效率 ⭐️⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
测试覆盖度 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
自动生成用例 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️

接口自动化测试在企业中的实践

接口自动化测试与 Web/App 自动化测试对比

Web/App 自动化测试 接口自动化测试
成本 ⭐️⭐️⭐️ ⭐️
测试效率 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
用例编写效率 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
稳定性 ⭐️⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
自动化回归测试效率 ⭐️⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
测试覆盖度 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️
自动生成用例 ⭐️⭐️ ⭐️⭐️⭐️⭐️⭐️

接口自动化测试与 Web/App 自动化测试对比

看起来接口自动化测试什么都比 Web/App 自动化测试要好,为什么还要做 Web/App 自动化测试?

  • 接口关注数据无法触达用户体验。

接口自动化测试课程设计

接口自动化测试-中级

  • 掌握接口自动化测试体系
  • 掌握接口自动化测试用例设计方案
  • 掌握接口自动化测试工具Requests/REST-assured

形式 章节 描述
知识点 接口自动化测试框架介绍 使用最流行的 requests 进行接口测试
知识点 接口请求构造 http 请求头、请求参数、请求方法构造
知识点 接口测试断言 状态码、返回内容等断言
知识点 json、xml 请求 以 json、xml 结构化的格式发送请求
知识点 xml 响应断言 利用 xpath 进行断言
知识点 json 响应断言 利用 json path 进行断言
知识点 schema 响应断言 应对大量响应数据字段的格式断言
知识点 代理配置 利用代理分析测试脚本,排查请求错误

接口自动化测试实践课(6~12个课时)

  • 根据产品与需求的复杂度,课时长短不一
形式 章节 课时
实战 接口自动化测试实战 6~12 课时

接口自动测试实践案例

接口自动化测试企业实践

接口自动化测试-高级(选学)

  • 掌握接口加密情况下的测试方案
  • 掌握接口自动化测试中切换多套被测环境
  • 掌握接口自动化测试中多种协议的封装与设计方案
  • 掌握接口自动化测试中接口鉴权的多种情况与解决方案
  • 结合电子商城的接口自动化测试框架实战

形式 章节 描述
知识点 接口加密与解密 接口加密情况下的测试方案
知识点 多套被测环境 多套被测环境切换的测试方案
知识点 多协议封装设计 结合抽象工厂设计模式实现多协议封装
知识点 接口鉴权的多种情况与解决方案 token、cookie、auth 等多种接口认证与解决方案
实战 电子商城接口自动化测试框架实战 接口用例编写、框架设计

接口测试经典面试题(计算机网络)

形式 章节 描述
知识点 http与https 的区别 分析 http 与 https 的区别
知识点 get、post 区别 get 与 post 的本质区别与具体抓包解读
知识点 session、cookie、token 的区别 基于真实系统了解 session、cookie、token 的区别
知识点 tcp 三次握手与四次挥手 分析三次握手与四次挥手流程
知识点 tcp 与 udp 的区别 分析 tcp 与 udp 的区别

接口自动化测试实战演练

实战说明

  1. 设计接口自动化测试用例业务流程
  2. 编写接口自动化测试代码
  3. 优化接口自动化测试代码(选修)

相关知识点

形式 章节
知识点 接口测试基础概念
知识点 接口自动化测试框架介绍
知识点 接口请求方法
知识点 接口请求参数
知识点 接口请求头
知识点 接口请求体-json
知识点 接口响应断言
知识点 json 响应体断言

接口测试基础概念

抓包分析

HTTP协议

  • 请求
    • 请求行:method url protocol
    • 请求方法:GET、POST、PUT、DELETE、HEAD
    • 请求头: Host Cookie User-Agent
    • 请求参数 query
    • 请求体:JSON XML FORM
  • 响应:
    • 响应状态行
    • 响应头
    • 响应体

URI 和 URL

  • URI,统一资源标识符,用来唯一的标识一个资源。
  • URL,统一资源定位符,它是一种具体的 URI
  • URL 结构:https://www.baidu.com/s?wd=霍格沃兹&rsv_spt=1
    1. 协议:http
    2. 域名:www.baidu.com
    3. 端口:跟在域名后面,域名和端口之间使用“:”作为分隔符,非必须,如果省略端口部分将采用默认端口
    4. 路径:/s
    5. 请求参数:wd=霍格沃兹&rsv_spt=**1

HTTP 请求报文

> GET /uploads/user/avatar/31438/8216a3.jpg HTTP/1.1
> Host: ceshiren.com
> Accept-Encoding: deflate, gzip
> Connection: keep-alive
> Pragma: no-cache
> Cache-Control: no-cache
> User-Agent: Mozilla/5.0 
(Macintosh; Intel Mac OS X 10_15_0)
 AppleWebKit/537.36 
 (KHTML, like Gecko) 
 Chrome/80.0.3987.116 Safari/537.36
> Accept: image/webp,image/apng,image/*,*/*;q=0.8
> Referer: https://ceshiren.com/
> Accept-Language: en,zh-CN;q=0.9,zh;q=0.8
> Cookie: user_id=xx;

_homeland_session=xx;
>

HTTP 响应报文

< HTTP/1.1 200 OK
< Server: nginx/1.10.2
< Date: Thu, 12 Mar 2020 09:13:44 GMT
< Content-Type: image/png
< Content-Length: 11390
< Connection: keep-alive

为什么推荐 Requests

  • 是由 Python 实现的 API 测试框架。
  • 支持发起 POST, GET, PUT, DELETE 等请求。
  • 可以用来验证和校对响应信息。

官网地址: https://requests.readthedocs.io/en/latest/

Requests 优势

  • 功能全面:HTTP/HTTPS 支持全面。
  • 使用简单:简单易用,不用关心底层细节。
  • 定制性高:结合测试框架完成二次封装,比如 HttpRunner。

Requests 环境准备

  • 安装命令:pip install requests

常见 HTTP 请求方法构造

方法 说明
requests.request() 构造一个请求,支撑以下各方法的基础方法。
requests.get() 构造 HTTP 协议中的 GET 请求。
requests.post() 构造 HTTP 协议中的 POST 请求。
requests.put() 构造 HTTP 协议中的 PUT 请求。
requests.delete() 构造 HTTP 协议中的 DELETE 请求。

底层设计

演练环境

HTTP 协议知识回顾

  • URL 结构
  • HTTP 请求
  • HTTP 响应

具体详见《常见接口协议》录播

构造 GET 请求

  • requests.get(url, params=None, **kwargs)
    • url: 接口 url。
    • params:拼接在 url 中的请求参数。
    • **kwargs:更多底层支持的参数。
# 导入依赖
import requests

def test_get():
    # 定义接口的 url 和拼接在 url 中的请求参数
    url = "https://httpbin.ceshiren.com/get"
    # 发出 GET 请求,r 接收接口响应
    r = requests.get(url)
    # 打印接口响应
    logger.info(f"接口响应为 {r}")

构造请求方法

  • requests.request(method, url, **kwargs)
    • method: 请求方法。
      • GETOPTIONSHEADPOSTPUTPATCHDELETE
    • url: 接口 url。
    • **kwargs:更多底层支持的参数。
def request(method, url, **kwargs):
    """Constructs and sends a :class:`Request <Request>`.

    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
        object to send in the body of the :class:`Request`.
    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
        to add for the file.
    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
    :param timeout: (optional) How many seconds to wait for the server to send data
        before giving up, as a float, or a :ref:`(connect timeout, read
        timeout) <timeouts>` tuple.
    :type timeout: float or tuple
    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
    :type allow_redirects: bool
    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
    :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response

底层参数说明

参数 应用场景
method 请求方法
url 请求 URL
params 请求中携带 URL 参数
data 请求中携带请求体(默认为表单请求)
json 请求中携带 json 格式的请求体
headers 请求中携带头信息
cookies 请求中携带 cookies
files 请求中携带文件格式的请求体
auth 请求中携带认证信息
timeout 设置请求超时时间
allow_redirects 请求是否允许重定向
proxies 设置请求代理
verify 请求是否要认证
cert 请求中携带 ssl 证书

请求参数简介

案例: https://ceshiren.com/search?expanded=true&q=requests

  • 接口请求中携带的,会在路径之后使用?代表客户端向服务端传递的参数。
  • 使用 key=value 形式拼接在 URL 中。
  • 如果有多个,则使用&分隔

携带请求参数的方式

  • 常用两种方式:
    • 直接在 URL 中拼接:?username=Hogwarts&id=666
    • 通过 params 参数传递:requests.get(url, params)

携带请求参数的 GET 请求

# 导入依赖
import requests

def test_get_by_params():
    # 定义接口的 url 和拼接在 url 中的请求参数
    url = "https://httpbin.ceshiren.com/get"
    params ={
        "get_key": "get_value"
    }
    # 发出 GET 请求,r 接收接口响应
    r = requests.get(url, params=params)


def test_get_by_url():
    # 定义接口的 url 和拼接在 url 中的请求参数
    url = "https://httpbin.ceshiren.com/get?get_key=get_value"
    # 发出 GET 请求,r 接收接口响应
    r = requests.get(url)

请求头信息的使用场景

  • 身份认证
  • 指定数据类型

飞书接口文档

请求头信息

  • HTTP 请求头是在 HTTP 请求消息中包含的元数据信息,用于描述请求或响应的一些属性和特征。
  • 实际工作过程中具体要关注的头信息字段需要和研发沟通。
  • 常见的头信息(右侧表格):
内容 含义
Authorization 表示客户端请求的身份验证信息
Cookie 表示客户端的状态信息,通常用于身份验证和会话管理
Content-Type 表示请求消息体的 MIME 类型
User-Agent 发送请求的客户端软件信息

构造头信息

  • 使用 headers 参数传入。
  • 通常使用字典格式。
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)

接口请求体简介

  • 进行HTTP请求时,发送给服务器的数据。
  • 数据格式类型可以是JSON、XML、文本、图像等格式。
  • 请求体的格式和内容取决于服务器端API的设计和开发人员的要求。

飞书接口文档

常用接口请求体

类型 介绍 Content-type
JSON(JavaScript Object Notation) 轻量级的数据交换格式,最常见的一种类型。 application/json
表单数据(Form Data) 以键值对的形式提交数据,例如通过 HTML 表单提交数据。 application/x-www-form-urlencoded
XML(eXtensible Markup Language) 常用的标记语言,通常用于传递配置文件等数据。 application/xml
text/xml
文件(File) 可以通过请求体上传文件数据,例如上传图片、视频等文件。 上传文件的 MIME 类型,例如 image/jpeg
multipart/form-data
纯文本(Text) 纯文本数据,例如发送邮件、发送短信等场景 text/plain
其他格式 二进制数据、protobuf 等格式

JSON 简介

  • 是 JavaScript Object Notation 的缩写。
  • 是一种轻量级的数据交换格式。
  • 是理想的接口数据交换语言。
  • Content-Type 为 application/json。

JSON 格式请求体示例

  1. 进入登录页面。
  2. 打开开发者工具。
  3. 输入用户名密码,点击登录。

https://litemall.hogwarts.ceshiren.com/#/login

构造 JSON 格式请求体

  • 定义为字典格式。
  • 使用 json 参数传入。
# 导入依赖
import requests

def test_post_json():
    # 定义接口的 url 和 json 格式请求体
    url = "https://httpbin.ceshiren.com/post"
    params = {
        "post_key": "post_value"
    }
    # 发出 POST 请求,r 接收接口响应
    r = requests.post(url, json=params)

接口断言使用场景

  • 问题:
    1. 如何确保请求可以发送成功。
    2. 如何保证符合业务需求。
  • 解决方案:
    • 通过获取响应信息,验证接口请求是否成功,是否符合业务需求。

Requests 中的响应结果对象

import requests
from requests import Response

# Response就是一个响应对象
r: Response = requests.get('http://www.example.com')

响应结果类型

属性 含义
r 响应 Response 对象(可以使用任意的变量名)
r.status_code HTTP 响应状态码
r.headers 返回一个字典,包含响应头的所有信息。
r.text 返回响应的内容,是一个字符串。
r.url 编码之后的请求的 url
r.content 返回响应的内容,是一个字节流。
r.raw 响应的原始内容
r.json() 如果响应的内容是 JSON 格式,可以使用该方法将其解析成 Python 对象。
# 导入依赖
import requests

def test_res_assert():
    # 定义接口的 url 和 json 格式请求体
    url = "https://httpbin.ceshiren.com/get"
    # 发出 GET 请求,r 接收接口响应
    r = requests.post(url)

响应状态码断言

  • 基础断言:
    • r.status_code
import requests

def test_req():
    r = requests.get("https://httpbin.ceshiren.com/get")
    assert r.status_code == 200

什么是 JSON 响应体

  • JSON格式的响应体指的是HTTP响应中的消息体(message body),它是以JSON格式编码的数据。
{
  "name": "John",
  "age": 30,
  "city": "New York"
}

断言 JSON 格式响应体使用场景

  • 验证API接口的返回结果是否符合预期。
    • 业务场景上是否符合预期。
    • 格式是否符合文档规范。

断言 JSON 格式响应体

  • r.json():返回 python 字典。
import requests

def test_res_json():
    r = requests.get("https://httpbin.ceshiren.com/get")
    assert r.status_code == 200
    assert r.json()["url"] == "https://httpbin.ceshiren.com/get"

若碰到复杂断言应该如何理?

  • 多层嵌套的数据提取与断言: JSONPath
  • 整体结构响应断言: JSONSchema
  • 自行编写解析算法