目录

1. 接口自动化的流程

1.1 挑选自动化接口

1.2 编辑接口测试用例

1.2.1 根据接口设计

1.2.2 结合业务逻辑设计

2. code

2.1 创建 Python 项目

2.2. 安装 requests 库

2.3 发送 http 请求

2.3.1 Response 对象

2.3.2 requests 提供的请求方法

2.3.2.1 请求方法参数


接口分为两种:

  1. 程序内部的接口: 所谓程序内部接口, 就是程序内部的方法与方法之间, 模块与模块之间, 互相调用的接口. 比如: 我们使用一个未登录的账号在 CSDN 点击发布博客时, 就会弹出登录界面, 要求我们必须登录后, 才可以发布博客, 此时, 就是 “发布博客接口, 调用了用户登录接口”.
  2. 系统对外的接口: 提供给用户使用的接口(比如我要在一个博客系统上查看一个博客, 服务器不可能直接把数据库给我们, 而是提供给用户一个查询博客的接口)

1. 接口自动化的流程

进行接口自动化的流程如下:

  1. 需求分析
  2. 挑选自动化接口
  3. 编写接口测试用例.
  4. 搭建自动化测试环境
    1. 选择编程语言 和 开发环境(IDE)
    2. 安装所需库.(Python: requests)
  5. 设计自动化框架(哪些包 [测试包/通用工具包/测试报告] /不同包放哪些代码)
  6. 编写代码.
  7. 执行测试用例(用例都转化成了代码)
  8. 输出测试报告.

1.1 挑选自动化接口

一个项目的接口是非常多的, 我们是无法保证覆盖所有的接口的.

我们可以从以下几个角度挑选自动化接口:

  1. 功能复杂度: 优选挑选功能复杂, 逻辑分支多的接口. 如: 涉及多种支付方式/订单状态的转换
  2. 高风险功能: 优先挑选风险高的接口. 如: 涉及资金的支付接口.
  3. 重复性高: 自动化的一个重要目的, 就是为了解决重复的测试功能, 因此挑选一些重复性高的测试接口. 如: 登录接口.
  4. 不易改变的接口: 避免对自动化代码进行频繁的维护.

1.2 编辑接口测试用例

对挑选好的接口, 设计接口测试用例.

设计接口测试用例, 需要从两方面去考虑:

  1. 通过接口设计测试用例
  2. 结合业务逻辑设计测试用例.

1.2.1 根据接口设计

通过接口设计测试用例,  我们可以从以下几个方面去考虑:

  1. 通过性验证(正向测试): 传入正确的参数, 返回的结果是否符合接口文档.
  2. 参数组合: 
    1. 必选参数与可选参数组合:只传必选参数;必选参数+部分可选参数;必选参数+全部可选参数
    2. 不同参数值的组合:例如一个接口有“状态”和“类型”两个参数,需要测试不同状态和不同类型的组合情况,看筛选结果是否正确
    3. 边界值组合:如果参数有范围(如年龄、数量),需要测试其有效范围的边界值组合
  3. 安全性验证:
    1. 是否存在 SQL 注入: ' or 1 = 1 --
    2. 是否存在饶过问题: 购买一个商品, 付款时通过工具把价格修改为 0/负数.(后端没有进行饶过校验)
    3. 是否存在越权问题:
      1. 垂直越权: 普通用户是否可以进行管理员的操作.
      2. 水平越权: 普通用户 A 是否能够看到普通用户 B 的信息.
    4. 是否有强制用户登录操作(Cookie-session/token): 如果用户没有登录, 一些功能是无法使用的.
    5. 参数是否经过加密(https): 若使用 http, 参数是明文传输的, 别人抓个包就能看到.
    6. 密码是否有复杂性校验
  4. 异常验证: 不按照接口文档的要求传入正确的参数, 而是故意传入错误数据. 如: 必传参数就不传/int 传 String/传 null

1.2.2 结合业务逻辑设计

这就需要结合公司具体的业务了.

比如:

一个博客系统, 用户连续 5 次登录失败, 就需要等待 15min, 才能再一次登录.

新用户注册完 5 天后, 才能进行发帖操作.

用户发的帖子抄过 n 个人点赞, 可以获得 x 积分.

2. code

2.1 创建 Python 项目

2.2. 安装 requests 库

安装 requests 库(第三方库, 用于发送 http 请求):

pip install requests==2.31.0

 查看是否安装成功: pip list (查看当前所安装库)

2.3 发送 http 请求

安装好 requests 库后, 我们就可以调用 requests.get/requests.post 向后端服务器发送 http GET/POST 请求.

requests.get / requests.post 返回的是一个 Response 对象, 这个 Response 对象包含了响应中的信息:

import requests

# 调用 get 方法向百度首页发送 GET 请求.
# requests.get 返回的是一个 Response 对象, 这个对象包含了响应中的信息.
response = requests.get("https://www.baidu.com")

# 打印 Response 对象
print(response)
# 打印 URL
print(response.url)
# 打印响应中的文本信息
print(response.text)

2.3.1 Response 对象

通过 requests 发送请求, 会返回一个 Response 对象, 这个 Response 对象中包含了响应中的信息.

常用的 Response 方法如下:

属性/方法描述
r.status_code响应状态码
r.content字节方式的响应体, 会自动解码 gzip 和 deflate 压缩
r.headers以字典对象存储服务器响应头, 若键不存在则返回 None
r.json()Requests 中内置的 JSON 解析方法, 将响应体解析为 JSON 格式
r.url获取实际请求的 URL
r.encoding编码格式, 根据响应头部的字符编码确定
r.cookies获取服务器设置的 cookies
r.raw返回原始响应体, 不进行任何处理
r.text字符串方式的响应体, 会自动根据响应头部的字符编码进行解码
r.raise_for_status()失败请求 (非200响应) 抛出异常

需要注意的是:

如果响应的 body 是 Json 格式的, 那么强烈推荐使用 r.json() 来获取响应内容(直接得到一个 Python 字典, 可以通过键获取对应的值), 使用 r.text 也可以获取, 但是只会把 Json 当作一个普通的字符串返回.

如果响应的 body 是 HTML 格式的, 那么必须使用 r.text 来获取正文, 否则报错:

2.3.2 requests 提供的请求方法

  1. requests.get(url, params=None, **kwargs)
  2. requests.post(url, data=None, json=None, **kwargs)
  3. requests.request(method, url, **kwargs)

其中, requests.get 发送 get 形式的 http 请求. requests.post 发送 post 形式的 http 请求.

而 requests.request 可以发送所有方式的 http 请求, 在 method 传入指定的方式即可.

# GET 请求.
get = requests.get("https://www.baidu.com")
# POST 请求.
post = requests.post("https://www.baidu.com")
# GET 请求, "GET" 大写或小写都可以, 推荐大写.
req_get = requests.request("GET", "https://www.baidu.com")
# POST 请求, "POST" 大写或小写都可以, 推荐大写.
req_post = requests.request("POST", "https://www.baidu.com")
2.3.2.1 请求方法参数

上面说到, 常用的 requests 方法有:

  1. requests.get(url, params=None, **kwargs)
  2. requests.post(url, data=None, json=None, **kwargs)
  3. requests.request(method, url, **kwargs)

其中, **kwargs 表示可以传更多的参数:

这些参数的含义如下:

参数名描述
url请求的接口
headers(请求头)一个字典,包含要发送的HTTP头。
cookies(请求头)一个字典、列表或者 RequestsCookieJar 对象,包含要发送的cookies。
files一个字典,包含要上传的文件。
data(请求参数, post 请求, form 表单格式的参数)一个字典、列表或者字节串,包含要发送的请求体数据。
json(请求参数, post 请求, json 格式的参数)一个字典,将被转换为JSON格式并发送。
params(请求参数, get 请求的参数)一个字典、列表或者字节串,将作为查询字符串附加到URL上。
auth一个元组,包含用户名和密码,用于HTTP认证。
timeout一个浮点数或元组,指定请求的超时时间。
proxies一个字典,包含代理服务器的信息。
verify一个布尔值或字符串,指定是否验证SSL证书。

注意: 当我们使用 requests 发送一个携带 json/form 参数的 post 请求时(即将一个 Python 字典传递给 post/request 方法的 json/data 参数时), requests 会自动帮我们把请求中的 Content-Type 设置为 application/json 或者 application/x-www-form-urlencoded, 无需我们手动去 header 中设置, 非常方便.

你使用的参数你的数据格式requests 自动设置的 Content-Type
json={'key': 'value'}JSON 数据application/json
data={'key': 'value'}表单数据application/x-www-form-urlencoded
files={'file': ...}文件上传(表单)multipart/form-data

举个例子:

测试博客登录接口:

博客登录接口是一个 post 请求, 那我们必须将登录的参数信息, 传入 request.post/request 方法的 json 形参上:

测试博客详情页接口:

由于 博客详情页接口是 get 请求, 因此参数既可以写在 URL 上, 也可以通过 requests.request 方法传入.

# 请求博客详情页接口.

# 1. 方式一: 参数直接写在 url 中.
url = 'http://47.93.87.16:8080/blog/getBlogDetail?blogId=31'
header = { # 身份验证信息.
    'user_token': 'eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjJjYjM4MTI5NTYxYTQzOTRiZGI0NTUxYmQyNDIyNjhlNTkyMzRjMzJhODg1OTlkNTFhNDZkNWJmYjc0Nzk3MjkiLCJpZCI6MiwidXNlck5hbWUiOiJsaXNpIn0.3u3ujG1kKR6s7IrFBMSEEkCw-ee5J9R6cdQj7F2KyPE'
}
res = requests.request(method='GET', url=url, headers=header)
print('方式一: ', res.json())

# 2. 方式二: 参数通过方法参数传入.
url = 'http://47.93.87.16:8080/blog/getBlogDetail'
param = {
    'blogId': 32
}
header = { # 身份验证信息.
    'user_token': 'eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjJjYjM4MTI5NTYxYTQzOTRiZGI0NTUxYmQyNDIyNjhlNTkyMzRjMzJhODg1OTlkNTFhNDZkNWJmYjc0Nzk3MjkiLCJpZCI6MiwidXNlck5hbWUiOiJsaXNpIn0.3u3ujG1kKR6s7IrFBMSEEkCw-ee5J9R6cdQj7F2KyPE'
}
res = requests.request(method='GET', url=url, headers=header, params=param)
print('方式二: ', res.json())

END

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐