大纲
- 行业对于接口测试的需求
- 接口测试的学习体系/课程设计
- 接口自动化测试的学习体系/课程设计
- 接口自动化测试实战练习
接口测试概念
- 接口:不同的系统之间相互连接的部分,是一个传递数据的通道
- 接口测试:检查数据的交换、传递和控制管理过程
- 使用场景:针对于前后端分离的产品(基本上市面上的绝大部分产品)
接口测试的价值
名企的接口文档
接口测试工具类型
测试类型 |
工具 |
接口数据分析 |
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 |
课程设计
- 由浅入深
- 根据课时的不同选择不同的难度
- 实践和理论结合
理论课-接口测试初级
- 掌握接口测试的知识体系与学习路线
- 掌握常用接口测试工具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课时 |
接口自动化测试场景
|
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 的区别 |
实战说明
- 设计接口自动化测试用例业务流程
- 编写接口自动化测试代码
- 优化接口自动化测试代码(选修)
相关知识点
形式 |
章节 |
知识点 |
接口测试基础概念 |
知识点 |
接口自动化测试框架介绍 |
知识点 |
接口请求方法 |
知识点 |
接口请求参数 |
知识点 |
接口请求头 |
知识点 |
接口请求体-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
- 协议:
http
- 域名:
www.baidu.com
- 端口:跟在域名后面,域名和端口之间使用“:”作为分隔符,非必须,如果省略端口部分将采用默认端口
- 路径:
/s
- 请求参数:
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 优势
- 功能全面: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 协议知识回顾
具体详见《常见接口协议》录播
构造 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: 请求方法。
GET
,OPTIONS
,HEAD
,POST
,PUT
,PATCH
,DELETE
。
- 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 证书 |
携带请求参数的方式
- 常用两种方式:
- 直接在 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 格式请求体
# 导入依赖
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)
接口断言使用场景
- 问题:
- 如何确保请求可以发送成功。
- 如何保证符合业务需求。
- 解决方案:
- 通过获取响应信息,验证接口请求是否成功,是否符合业务需求。
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)
响应状态码断言
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 格式响应体使用场景
断言 JSON 格式响应体
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
- 自行编写解析算法