接口自动化测试
接口自动化测试
学习价值
学习目标
- 掌握接口自动化测试体系。
- 掌握接口自动化测试用例设计方法。
知识模块
- 接口自动化测试 L1
实战需求
实战 1:PetClinc 宠物主人搜索接口
PetClinic_Rest 是一个宠物诊所管理系统的后端 RESTful API 接口,为前端提供了宠物、医生、预约等相关数据的增删改查功能。
- https://spring-petclinic-rest.k8s.hogwarts.ceshiren.com/petclinic/swagger-ui/index.html#/
接口文档
请求方式: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 |
宠物主人的手机号码 |
实战要求
- 设计接口测试用例
- 编写接口自动化测试用例
实战 2:宠物商店接口测试
- 对宠物商店宠物管理接口完成自动化冒烟测试
- 宠物商店接口文档:https://petstore.swagger.io
- 查询宠物接口
- 新增宠物接口
- 更新宠物接口
- 删除宠物接口
- 添加 allure 描述并生成 allure 报告
相关知识点
教程地址 | 教程视频地址 | 时间位置 |
---|---|---|
接口自动化测试框架介绍 | 接口自动化测试框架介绍 | 全部 19:43 |
接口请求方法 | 接口请求方法 | 全部 22:50 |
接口请求参数 | 接口请求参数 | 全部 13:21 |
接口请求头 | 接口请求头 | 全部 8:57 |
接口请求体-json | 接口请求体-json | 全部 11:55 |
接口响应断言 | 接口响应断言 | 全部 10:55 |
json 响应体断言 | json 响应体断言 | 全部 13:16 |
实战演练
实战 1:PetClinc 宠物主人搜索接口
import allure
import pytest
import requests
@allure.epic("宠物医院")
@allure.feature("搜索功能")
class TestOwnerSearch:
def setup_class(self):
# 查询宠物主人 url
self.owner_url = "https://spring-petclinic-rest.k8s.hogwarts.ceshiren.com/petclinic/api/owners"
# 现存宠物主人数量(值可能会变,执行用例前需要确认)
self.owner_num = 105
@pytest.mark.P0
@allure.story("Owners搜索")
@allure.title("搜索存在主人-冒烟用例")
def test_search_owner(self):
'''
【冒烟】存在的 LastName 可以正确获取宠物主人信息
'''
# 搜索关键词
search_key = "Green"
# 拼接请求参数(拼接在 url 后的参数)
param = {
"lastName": search_key
}
# 发出 get 请求,并携带请求参数
r = requests.get(self.owner_url, params=param)
# 打印响应体
print(r.text)
# 断言获取到的查询结果不为空
assert len(r.json()) > 0
# 断言查询到的第一个结果的 lastName 的值符合预期
assert r.json()[0].get("lastName") == "Green"
@pytest.mark.P0
@allure.story("Owners搜索")
@allure.title("搜索全部主人-冒烟用例")
def test_search_allowner(self):
'''
【冒烟】无 LastName 获取全量宠物主人信息
'''
# 发出 get 请求
r = requests.get(self.owner_url)
# 打印响应体
print(r.text)
# 断言获取到的查询结果数量大于等于已经有的宠物主人数量
assert len(r.json()) >= self.owner_num
assert "Green" in r.text
@pytest.mark.P1
@allure.story("Owners搜索")
@allure.title("搜索主人-模糊搜索测试")
@pytest.mark.parametrize(
"search_key",
["a", "b", "A"]
)
def test_search_only_exists_params(self, search_key):
"""
输入部分字母,获取此字母开头的主人信息
使用小写字母能搜索到大写字母的主人信息
使用大写字母能搜索到小写字母的主人信息
"""
# 打印搜索关键词
print(f"搜索关键词为:{search_key}")
# 拼接请求参数(拼接在 url 后的参数)
param = {
"lastName": search_key
}
# 发出 get 请求,并携带请求参数
r = requests.request("GET", url=self.owner_url, params=param)
# 获取宠物主人列表
owner_list = r.json()
# 断言比较结果列表的长度大于等于1
assert len(owner_list) >= 1
# 获取搜索第一个结果的 lastName 值
name = owner_list[0].get("lastName")
print(f"取出结果列表中的姓氏为: {name}")
# 断言比较接口返回结果列表中的字典中姓氏与查询的参数一致
assert search_key or search_key.upper() or search_key.lower() in name
@pytest.mark.P1
@allure.story("Owners搜索")
@allure.title("搜索主人-结果不存在")
def test_search_not_exists(self):
"""
使用不存在的字母姓氏搜索
"""
search_key = "xxx"
param = {
"lastName": search_key
}
code = requests.request("GET", url=self.owner_url, params=param).status_code
# 断言响应码为404
assert code == 404
@pytest.mark.P2
@allure.story("Owners搜索")
@allure.title("搜索主人-异常输入值")
@pytest.mark.parametrize(
"owner_url",
["hogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwartshogwarts",
"涨", "123", "###"]
)
def test_search_not_exists(self, owner_url):
"""
使用超长的姓氏搜索
使用中文姓氏搜索
使用数字姓氏搜索
使用符号进行搜索
"""
print(f"给接口设定输入内容:{owner_url}")
param = {
"lastName": owner_url
}
code = requests.request("GET", url=self.owner_url, params=param).status_code
# 断言响应码为404
assert code == 404
实战 2:宠物商店接口测试
import allure
import requests
@allure.feature("宠物商店宠物信息接口测试")
class TestPetstore:
def setup_class(self):
'''
准备测试数据
:return:
'''
# 请求的基础 url
self.url = "https://petstore.swagger.io/v2/pet"
# 要操作的宠物 id
self.pet_id = 9223372000001083222
# 查询状态
self.find_parmas = {
"status": "available"
}
# 新增宠物的数据
self.add_data = {
"id": self.pet_id,
"category": {
"id": 1,
"name": "cat"
},
"name": "miao",
"photoUrls": [
"string"
],
"tags": [
{
"id": 5,
"name": "cute"
}
],
"status": "available"
}
# 更新宠物的数据
self.update_data = {
"id": self.pet_id,
"category": {
"id": 1,
"name": "cat"
},
"name": "小小",
"photoUrls": [
"string"
],
"tags": [
{
"id": 5,
"name": "cute"
}
],
"status": "available"
}
@allure.story("查询宠物接口冒烟用例")
def test_getpet(self):
'''
获取宠物信息
:return:
'''
get_url = self.url + "/findByStatus"
with allure.step("发出查询接口请求"):
r = requests.get(get_url, self.find_parmas, verify=False)
with allure.step("获取查询接口响应"):
print(r.json())
with allure.step("查询接口断言"):
assert r.status_code == 200
assert "id" in r.text
@allure.story("新增宠物接口冒烟用例")
def test_addpet(self):
'''
新增宠物信息
:return:
'''
with allure.step("发出新增接口请求"):
r = requests.post(self.url, json=self.add_data, verify=False)
with allure.step("获取新增接口响应"):
print(r.json())
with allure.step("新增接口断言"):
assert r.status_code == 200
assert r.json() == self.add_data
@allure.story("更新宠物接口冒烟用例")
def test_updatepet(self):
'''
更新宠物信息
:return:
'''
with allure.step("发出更新接口请求"):
r = requests.put(self.url, json=self.update_data, verify=False)
with allure.step("获取更新接口响应"):
print(r.json())
with allure.step("更新接口断言"):
assert r.status_code == 200
assert r.json() == self.update_data
@allure.story("删除宠物接口冒烟用例")
def test_deletepet(self):
'''
删除宠物信息
:return:
'''
delete_url = self.url + "/" + str(self.pet_id)
with allure.step("发出删除接口请求"):
r = requests.delete(delete_url, verify=False)
with allure.step("获取删除接口响应"):
print(r.json())
with allure.step("删除接口断言"):
assert r.status_code == 200
assert r.json()["message"] == str(self.pet_id)
总结
- 掌握接口自动化测试体系。
- 掌握接口自动化测试用例设计方法。