目录
PetClinic 宠物主人搜索接口¶
请求方式:GET(HTTPS)¶
请求地址:https://spring-petclinic-rest.k8s.hogwarts.ceshiren.com/petclinic/api/owners?lastName=LASTNAME¶
请求参数说明¶
| 参数 | 必须 | 说明 |
|---|---|---|
| lastName | 否 | 输入宠物主人 Last name,长度不超过 1~80 个字母 |
权限说明¶
暂不进行权限控制
返回结果¶
[
{
"address": "110 W. Liberty St.",
"city": "Madison",
"firstName": "George",
"id": 1,
"lastName": "Franklin",
"pets": [
{
"birthDate": "2022-10-31",
"id": 1,
"name": "Leo",
"ownerId": 1,
"type": {
"id": 1,
"name": "cat"
},
"visits": [
{
"date": "2022-10-31",
"description": "rabies shot",
"id": 1,
"petId": 1
}
]
}
],
"telephone": "6085551023"
}
]
返回参数说明¶
| 参数 | 说明 |
|---|---|
| address | 宠物主人的地址 |
| city | 宠物主人的城市 |
| firstName | 宠物主人的名字 |
| id | 宠物主人的id |
| lastName | 宠物主人的姓氏 |
| pets | 宠物的信息 |
| pets.birthDate | 宠物的生日 |
| pets.id | 宠物的id |
| pets.name | 宠物的名字 |
| pets.ownerId | 宠物主人的id |
| pets.type | 宠物的类型 |
| pets.type.id | 宠物的类型的id |
| pets.type.name | 宠物的类型的名称 |
| pets.visits | 宠物访问记录 |
| pets.visits.date | 宠物访问记录的日期 |
| pets.visits.description | 宠物访问记录的描述信息 |
| pets.visits.id | 宠物访问记录的id |
| pets.visits.petId | 宠物访问记录访问的宠物id |
| telephone | 宠物主人的手机号码 |
| ## 应用场景说明 |
接口测试是一个非常重要的阶段,也是现在的测试过程中必不可少的阶段。
接口测试的好处:
- 发现的 Bug 越早,修复成本越低
- 检查系统的安全性和稳定性
- 系统复杂性不断增加,传统的测试方法成本急剧上升,测试效率大大降低
针对于宠物主人搜索功能场景是一个核心场景,需要对该接口的搜索场景进行覆盖测试。这里会使用到以下接口自动化测试相关技术:
- 自动化工具:Requests
- 测试框架:Pytest
- 测试报告:Allure
环境准备¶
测试框架准备¶
参考测试框架准备部分内容。
Requests 的安装¶
- 前提:
- 配置好 Python 环境
- 配置好 pip 工具
- 安装:
pip install requests
自动化测试需求理解¶
根据接口文档中规定的接口信息进行设计。
接口请求参数只有一个,宠物主人的姓氏 lastName 字段,非必填,有长度限制。
根据接口测试用例设计的思路,需要对 lastName 字段设置正常传递、不传、不同类型参数值、不同长度值等等测试场景和数据来覆盖测试。
自动化测试用例设计¶
接口测试用例采用表格形式设计,和功能测试用例类似。
需要包含以下内容:
- 用例编号
- 模块
- 测试点
- 前置条件
- 接口地址(URL)
- 请求方法
- 请求参数
- 预期结果
- 实际结果
表格形式的接口用例展示如下
| 用例编号 | 模块 | 测试点 | 前置条件 | URL | 请求方法 | 请求参数 | 预期结果 | 实际结果 |
|---|---|---|---|---|---|---|---|---|
| c_001 | 获取宠物主人接口验证 | 【冒烟】存在的姓氏可以正确获取宠物主人信息 | http://k8s03.hogwarts.ceshiren.com:39966/petclinic/api/owners | get | lastName=Green | 接口功能正常,正确获取到宠物主人的信息 [ { "firstName": "George", "lastName": "Green", "address": "110 W. Liberty St.", "city": "Madison", "telephone": "6085551023", "id": 155, "pets": [] } ] |
具体的测试用例信息请参考:
接口自动化测试用例¶
测试用例编写¶
使用 pytest 测试类组织测试用例。在测试类中编写具体的测试方法,每一个测试方法是一个测试用例。
在每一条测试用例中,使用 requests 发起请求。接受接口响应内容,然后进行断言,判断用例是否通过。
class TestOwnerSearch:
OWNER_URL = "https://spring-petclinic-angular.poc.ceshiren.com/petclinic/api/owners"
def test_search_more_exists(self):
"""
测试步骤:
1. 设定lastName的值为【searchkey】
2. 使用设定的参数发起requests请求
3. 取出requests请求的结果
预期结果:结果数量大于=2 不止一个
:return:
"""
searchkey = "Davis"
param = {"lastName": searchkey}
ownerlist = requests.request("GET", url=self.OWNER_URL, params=param).json()
assert len(ownerlist) >= 2
添加日志¶
编写日志工具类
import logging
import os
from logging.handlers import RotatingFileHandler
# 绑定绑定句柄到logger对象
logger = logging.getLogger(__name__)
# 获取当前工具文件所在的路径
root_path = os.path.dirname(os.path.abspath(__file__))
# 拼接当前要输出日志的路径
log_dir_path = os.sep.join([root_path, f'/logs'])
if not os.path.isdir(log_dir_path):
os.mkdir(log_dir_path)
# 创建日志记录器,指明日志保存路径,每个日志的大小,保存日志的上限
file_log_handler = RotatingFileHandler(os.sep.join([log_dir_path, 'log.log']), maxBytes=1024 * 1024, backupCount=10)
# 设置日志的格式
date_string = '%Y-%m-%d %H:%M:%S'
formatter = logging.Formatter(
'[%(asctime)s] [%(levelname)s] [%(filename)s]/[line: %(lineno)d]/[%(funcName)s] %(message)s ', date_string)
# 日志输出到控制台的句柄
stream_handler = logging.StreamHandler()
# 将日志记录器指定日志的格式
file_log_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)
# 为全局的日志工具对象添加日志记录器
# 绑定绑定句柄到logger对象
logger.addHandler(stream_handler)
logger.addHandler(file_log_handler)
# 设置日志输出级别
logger.setLevel(level=logging.INFO)
在测试用例中添加日志
logger.info(f"给接口设定输入内容:{searchkey}")
参数化¶
如果多个测试用例,测试步骤完全相同,只有测试数据不同,可以使用参数化的方式,在一个测试方法中完成多个测试用例的执行。
@pytest.mark.parametrize("searchkey", ["a", "b", "A"])
def test_search_only_exists(self, searchkey):
...
设置测试用例优先级¶
使用 pytest 添加标签的特性,为测试用例设置优先级。这样可以方便单独执行其中一种优先级的测试用例。
在 pytest.ini 文件中声明用例优先级
[pytest]
markers = P0
P1
P2
在测试用例中添加优先级
@pytest.mark.P0
def test_search_more_exists(self):
...
添加测试报告¶
使用 allure,在测试用例的不同位置添加测试报告信息。
@allure.epic("宠物医院")
@allure.feature("搜索功能")
class TestOwnerSearch:
OWNER_URL = "http://spring-petclinic-angular.poc.ceshiren.com/owners"
@pytest.mark.P0
@allure.story("Owners搜索")
@allure.title("搜索-结果不止一个")
def test_search_more_exists(self):
...
测试代码¶
部分用例代码如下:
@allure.epic("宠物医院")
@allure.feature("搜索功能")
class TestOwnerSearch:
OWNER_URL = "https://spring-petclinic-angular.poc.ceshiren.com/petclinic/api/owners"
@pytest.mark.P0
@allure.story("Owners搜索")
@allure.title("搜索-结果不止一个")
def test_search_more_exists(self):
"""
测试步骤:
1. 设定lastName的值为【searchkey】
2. 使用设定的参数发起requests请求
3. 取出requests请求的结果
预期结果:结果数量大于=2 不止一个
:return:
"""
searchkey = "Davis"
logger.info(f"给接口设定输入内容:{searchkey}")
param = {"lastName": searchkey}
ownerlist = requests.request("GET", url=self.OWNER_URL, params=param).json()
logger.info("断言比较结果列表的长度大于2 len(ownerlist) >= 2")
assert len(ownerlist) >= 2
完整的自动化测试用例代码请查看源码:接口自动化测试代码
测试报告¶
使用命令执行接口测试用例项目,得到测试报告。
// 执行测试用例
pytest --alluredir=./result
// 生成测试报告
allure generate --clean result -o result/html
最终得到的测试报告如下:
- 首页

- 图表展示

- 功能页面
