文章目录
-
- 接口自动化测试流程
- [一、项目实战 - 需求分析](#一、项目实战 - 需求分析)
- 二、挑选接口
- 三、设计测试用例(脑图)
- 四、设计自动化测试项目的架构
- [五、 编写代码](#五、 编写代码)
-
- [5.1 封装工具类/方法](#5.1 封装工具类/方法)
-
- [5.1.1 封装请求](#5.1.1 封装请求)
- [5.1.2 封装yaml读取](#5.1.2 封装yaml读取)
- [5.1.3 封装日志](#5.1.3 封装日志)
- [5.2 用例编写](#5.2 用例编写)
-
- 1) 博客登录接口 博客登录接口)
- 2) 获取博客列表接口 获取博客列表接口)
- 3) 获取博客详情接口 获取博客详情接口)
- 4) 添加博客接口 添加博客接口)
- 5) 获取登录用户信息接口 获取登录用户信息接口)
- 6) 删除博客信息接口 删除博客信息接口)
- 六、执行测试用例
-
- [6.1 基础执行](#6.1 基础执行)
- [6.2 指定用例执行顺序](#6.2 指定用例执行顺序)
- 七、生成测试报告并分析结果
-
- [7.1 测试报告生成](#7.1 测试报告生成)
- [7.2 测试结果分析](#7.2 测试结果分析)

接口自动化测试流程
1. 需求分析
- 分析请求:明确接口的URL、请求方法(如get、post、PUT、DELETE等)、请求头、请求参数和请求体等信息。
- 分析响应:确定接口返回的数据格式、状态码以及可能的错误信息。
2. 挑选自动化接口
- 根据项目的时间、人员安排和接口的复杂度,挑选适合自动化测试的接口。
- 优先选择核心业务接口、频繁使用的接口以及容易出错的接口进行自动化测试,挑选依据主要包括:
功能复杂度: 优先选择功能复杂、逻辑分支多的接口进行自动化测试。例如,涉及多种支付方式、多种订单状态转换的订单管理接口,手动测试难以全面覆盖所有场景,自动化测试可以更高效地进行测试。
高风险功能: 选择对业务影响大、风险高的接口进行自动化测试,确保其稳定性和可靠性。例如,涉及资金操作的支付接口,一旦出现问题可能导致严重的经济损失,因此需要进行充分的自动化测试。
重复性高: 对于需要频繁执行的测试任务,如回归测试中的接口测试,自动化测试可以避免重复手动测试的繁琐和低效,提高测试效率。
3. 设计自动化测试用例
- 如果在功能测试阶段已经设计了测试用例,可以直接拿来使用。
- 根据接口需求和功能,设计正向测试用例(正常场景)和反向测试用例(异常场景),包括边界值测试、参数组合测试等。
4. 搭建自动化测试环境
- 选择合适的编程语言(如Python、Java等)和开发环境(如PyCharm、IntelliJ IDEA等)来实现自动化测试。
- 以Python为例,安装必要的依赖库,如requests用于发送HTTP请求,pytest用于测试框架。
5. 设计自动化执行框架
设计一个框架来执行测试用例,包括报告生成、参数化处理和用例执行逻辑。
6. 编写代码
根据设计好的测试用例和框架,编写自动化测试脚本。
7. 执行用例
使用测试框架(如unittest、pytest)来执行编写的测试用例。
8. 生成测试报告
测试完成后,生成测试报告。可以使用工具(如HtmlTestRunner或Allure)来生成易于阅读的报告。
一、项目实战 - 需求分析
理解业务需求,若是针对未参与的项目实施接口自动化,应与业务人员、产品经理等沟通,了解接口所支持的业务场景和业务逻辑。根据业务需求,明确接口需要实现的具体功能,如数据的获取、修改、删除等操作,以及接口的输入输出要求。分析接口之间的依赖关系,确定接口的调用顺序和依赖条件。
二、挑选接口
该博客系统中接口较少,可以针对所有的接口实施自动化测试。
若是大型项目,可按照接口自动化流程中挑选接口内容参考挑选。
部分接口示例如下:

三、设计测试用例(脑图)

针对接口设计测试用例,必须要按照完备接口文档来进行设计,除此之外,最好也能看到测试接口对应代码,查看接口存在的不同的响应,针对不同的响应来设计测试用例。
四、设计自动化测试项目的架构
语言选择: python
技术栈: pytest框架、requests模块、PyYAML模块、jsonschema模块、allure-pytest模块、logging 模块
集成开发环境: pycharm
项目目录结构:
autotest_interface/
├── cases/ # 所有测试脚本存放的目录--根据接口创建测试文件
│ ├── test_login.py # 示例:登录博客的测试用例
│ ├── test_edit.py # 示例:编辑博客的测试用例
│ └── ...
├── data/ # 存放通用数据目录
│ └── data.yaml # 通用数据文件
├── utils/ # 辅助工具和库的目录
│ ├── logger_util.py # 封装日志
│ ├── request_util.py # 封装接口请求
│ ├── yaml_util.py # 封装yaml操作
│ └── ...
├── allure-results/ # 测试结果输出目录
│ ├── xxxx.json
│ └── ...
├── allure-report/ # 测试报告输出目录
│ ├── index.html
│ └── ...
├── logs/ # 测试日志目录
│ ├── 2026-3-10/ # 按天划分的日志目录
│ │ ├── 2026-3-10_info.log # info日志
│ │ └── 2026-3-10_error.log # error日志
│ └── ...
└── pytest.ini # 运行配置文件
五、 编写代码
5.1 封装工具类/方法
对于测试类公共的代码部分,可以将其封装为公共类,便于所有用例测试调用。
5.1.1 封装请求
- 当前系统下,只要get和post两个请求,因此封装请求类中只需要处理get和post这两个请求。
- 使用 requests库,用于发送HTTP请求,并返回得到的服务器响应信息。
python
import requests
from utils.logger_util import logger
host = "http://8.64.84.36:8080"
# 封装请求方法
class Request:
log = logger.getlog()
def get(self,url,**kwargs):
self.log.info("准备发起get请求,url: " + url)
self.log.info("接口信息:{}".format(kwargs))
r = requests.get(url=url,**kwargs)
self.log.info("接口响应状态码:{}".format(r.status_code))
self.log.info("接口响应内容:{}".format(r.text))
return r
def post(self,url,**kwargs):
self.log.info("准备发起get请求,url: " + url)
self.log.info("接口信息:{}".format(kwargs))
r = requests.post(url=url,**kwargs)
self.log.info("接口响应状态码:{}".format(r.status_code))
self.log.info("接口响应内容:{}".format(r.json()))
return r
5.1.2 封装yaml读取
- 公共的数据可统一存放在yml文件中,例如token信息,除了登录接口不需要之外,所有的接口都需要token作为请求头信息才能进行正确测试。因此在工具类中封装处理yml的操作,便于所有测试类对yml进行读写操作。
python
'''
yaml 相关操作
'''
import os
import yaml
# 向yaml文件中写入数据
def write_yaml(filename,data):
file_path = os.getcwd() + "/data/" + filename
with open(file_path,mode='a+',encoding='utf-8') as f:
yaml.safe_dump(data,stream=f)
# 读取yaml文件中的数据, 若yaml文件中存在重复的字段, 读取yaml文件时取的是最新的字段对应的值
def read_yaml(filename,key):
file_path = os.getcwd() + "/data/" + filename
with open(file_path,mode='r',encoding='utf-8') as f:
data = yaml.safe_load(stream=f)
return data[key]
# 清空yaml文件
def clear_yaml(filename):
file_path = os.getcwd() + "/data/" + filename
with open(file_path, mode='w', encoding='utf-8') as f:
f.truncate()
读取yaml文件中的数据, 若yaml文件中存在重复的字段, 读取yaml文件时取的是最新的字段对应的值
5.1.3 封装日志
- 对于日志进行分日期分级别的存放,统一存放在logs文件下,以日期+日志级别进行命名(例:2026-3-11-info.log)并设置日志统一格式便于查看。
python
import logging
import os.path
import time
class infoFillter(logging.Filter):
def filter(self, record):
return record.levelno == logging.INFO
class errorFillter(logging.Filter):
def filter(self, record):
return record.levelno == logging.ERROR
class logger:
# 获取日志对象 -- 定义类方法
@classmethod
def getlog(cls):
# 创建日志对象
cls.logger = logging.getLogger(__name__)
cls.logger.setLevel(logging.DEBUG)
LOG_PATH = "./logs/"
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
# 将日志输出到日志文件中
now = LOG_PATH + time.strftime("%Y-%m-%d")
log_name = now + ".log"
info_log_name = now + "-info.log"
error_log_name = now + "-error.log"
# 创建文件处理器
all_handler = logging.FileHandler(log_name,encoding="utf-8")
info_handler = logging.FileHandler(info_log_name,encoding="utf-8")
error_handler = logging.FileHandler(error_log_name,encoding="utf-8")
# 创建处理器,将日志输出到控制台
streamHandler = logging.StreamHandler();
# 设置日志格式
formatter = logging.Formatter(
"%(asctime)s %(levelname)s [%(name)s] [%(filename)s (%(funcName)s:%(lineno)d)] - %(message)s"
)
all_handler.setFormatter(formatter)
info_handler.setFormatter(formatter)
error_handler.setFormatter(formatter)
streamHandler.setFormatter(formatter)
# 添加过滤器
info_handler.addFilter(infoFillter())
error_handler.addFilter(errorFillter())
cls.logger.addHandler(all_handler)
cls.logger.addHandler(info_handler)
cls.logger.addHandler(error_handler)
cls.logger.addHandler(streamHandler)
return cls.logger
5.2 用例编写
1) 博客登录接口
- 通过在线工具将接口返回json转换为schema,并使用
validate关键字进行接口测试的校验,验证接口返回信息是否符合预期(工具转换可能会出现部分错误,需要校验并手动更正,还可以增加一些额外约束校验) - 使用pytest框架
@pytest.mark.parametrize装饰器实现参数化,按照测试用例定义对应的多组参数,从而多次运行,提高测试效率和覆盖度,每添加一组用例参数即可进行一次测试验证是否无误。 - schema只能校验返回的信息是否为预期类型,还需
assert对关键数据验证是否为预期数据 - 登录接口返回数据包含token信息,是其他用例接口用以身份认证与权限校验的,所有在正常登录完成后需要将该token保存以供其他接口进行调用,对于此公共数据,调用yaml工具类存放在yaml文件中即可。
python
'''
登录 ------ 登录接口自动化测试
url = "http://8.64.84.36:8080/user/login"
json = {
"userName":"zhangsan",
"password":"123456"
}
'''
import re
import pytest
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import write_yaml
class testLogin:
url = host + "/user/login"
schema = {
"type": "object",
"required": ["code", "message", "data"],
"additionalProperties": False,
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string", "null"]
},
"data": {
"type": ["object","null"],
"required": ["userId","token"],
"properties": {
"userId": {
"type": "number"
},
"token": {
"type": ["string"]
}
}
}
}
}
# 异常登录
@pytest.mark.parametrize("login", [
# 错误的账号,错误的密码
{
"userName": "zhang",
"password": "123",
"message":"用户不存在"
},
# 错误的账号,正确的密码
{
"userName": "zhang",
"password": "123456",
"message": "用户不存在"
},
# 正确的账号,错误的密码
{
"userName": "zhangsan",
"password": "123",
"message": "密码不正确"
},
# 不存在的账号
{
"userName": "zhaoliu",
"password": "XXXXXX",
"message": "用户不存在"
},
# 账号密码都为空
{
"userName": "",
"password": "",
"message": ["用户名不能为空","密码不能为空"]
},
# 账号为空,密码不为空
{
"userName": "",
"password": "123456",
"message": "用户名不能为空"
},
# 账号不为空,密码为空
{
"userName": "zhangsan",
"password": "",
"message": "密码不能为空"
},
# 过长的账号
{
"userName": "aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb",
"password": "123456",
"message": "用户不存在"
},
# 过长的密码
{
"userName": "zhangsan",
"password": "aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb",
"message": "密码不正确"
},
# 账号密码过长
{
"userName": "aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb",
"password": "aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbb",
"message": "用户不存在"
},
])
def test_login_fail(self,login):
data = {
"userName": login["userName"],
"password": login["password"]
}
r = Request().post(url=self.url, json=data)
validate(instance=r.json(), schema=self.schema)
assert r.json()["code"] == -2
assert r.json()["message"] in login["message"]
assert r.json()["data"] is None
# 正常登录
@pytest.mark.parametrize("login",[
{
"userName": "zhangsan",
"password": "123456",
},
{
"userName": "lisi",
"password": "123456",
}
])
def test_login_success(self,login):
data = {
"userName":login["userName"],
"password":login["password"]
}
r = Request().post(url=self.url,json=data)
validate(instance=r.json(),schema=self.schema)
assert r.json()["code"] == 200
assert re.match('\S{100}',r.json()['data']['token'])
# 接口返回的token存储到yaml文件中
token = {
"user_token" : r.json()["data"]["token"]
}
write_yaml("data.yml",token)
2) 获取博客列表接口
- 博客列表接口没有参数,使用get请求获取列表信息。
- 该接口需要在请求头中添加有效的token字段信息,用于身份校验与登录凭证获取,实现登录状态模拟,否则将返回鉴权失败。token信息在登录接口测试后已存放在yaml文件中,对该文件的token数据进行读取并添加到header中即可。
- 同样,将接口返回json转换为schema进行格式类型的预期校验。并断言关键的数据是否为预期的返回值。
- 在博客详情接口需要blogId,而当前列表接口刚好返回所有的博客id,因此添加一个有效的blogId存入yaml文件供接下来的博客详情接口读取使用。
python
'''
博客列表 ------ 博客列表接口自动化测试
url = "http://8.64.84.36:8080/blog/getList"
header = {
"user_token" : "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibGlzaSIsImlkIjoyLCJleHAiOjE3NzM4MzY5OTh9.hhqXctG4EYH9z7PdSV1poYQkK3pJIpBc9Ssb7w-LA4o"
}
'''
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import read_yaml
class TestList:
url = host + "/blog/getList"
schema = {
"type": "object",
"required": ["code","message","data"],
"additionalProperties": False,
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string","null"]
},
"data": {
"type": "array",
# 要求返回的博客至少有一个
"minItems": 1,
"items": {
"type": "object",
"required": ["id","title","content","createTime"],
"additionalProperties": False,
"properties": {
"id": {
"type": "number"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"createTime": {
"type": "string"
}
}
}
}
}
}
# 未登录状态获取列表
def test_list_nologin(self):
r = Request().get(url=self.url)
assert r.status_code == 401
# 登录状态获取列表
def test_list_login(self):
token = read_yaml("data.yml","user_token")
header = {
"user_token" : token
}
r = Request().get(url=self.url,headers=header)
validate(r.json(),schema=self.schema)
assert r.json()["code"] == 200
# 提取有效的blogId 存储在yaml中
blogId = {
"blogId":r.json()["data"][0]["id"]
}
write_yaml("data.yml",blogId)
3) 获取博客详情接口
- 博客详情页参数为blogId,因为列表页已将有效id进行存储,可以从yaml中读取,且参数拼接在url上。
- 接口返回json同样转换为schema进行校验。
- 此处接口参数设计需按照测试用例进行给出,并按照测试用例进行接口测试代码编写。
- 参数一样使用pytest框架
@pytest.mark.parametrize进行参数化。
python
import pytest
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import read_yaml
class TestDetail:
url = host + "/blog/getBlogDetail?blogId="
schema = {
"type": "object",
"required": ["code","message","data"],
"additionalProperties": False,
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string","null"]
},
"data": {
"type": "object",
"required": ["id","title","content","userId","createTime"],
"additionalProperties": False,
"properties": {
"id": {
"type": "number"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"userId": {
"type": "number"
},
"createTime": {
"type": "string"
}
}
}
}
}
# 未登录状态下
def test_detail_nologin(self):
url = self.url + str(read_yaml("data.yml","blogId"))
r = Request().get(url=url)
assert r.status_code == 401
# 登录状态下
# 正常请求
def test_detail_login(self):
url = self.url + str(read_yaml("data.yml","blogId"))
token = read_yaml("data.yml","user_token")
header = {
"user_token":token
}
r = Request().get(url=url,headers=header)
validate(r.json(),self.schema)
assert r.json()["code"] == 200
assert r.json()["data"]["id"] == read_yaml("data.yml","blogId")
# 博客详情 ------ blogId错误 "",3,"abc",-100,9999999999999999999999999999999999
@pytest.mark.parametrize("blogId",[
# blogId 为空
{
"blogId":"",
"message":"[blogId 不能为null]"
},
{
"blogId":3,
"message":"Source must not be null"
},
])
def test_detail_fail(self,blogId):
params = {
"blogId":blogId["blogId"]
}
url = self.url + str(blogId["blogId"])
token = read_yaml("data.yml", "user_token")
header = {
"user_token": token
}
r = Request().get(url=url, headers=header)
assert r.json()["code"] == -2
assert r.json()["message"] == blogId["message"]
4) 添加博客接口
- 同样使用schema进行类型校验。
- 此处正常登录情况下将添加成功和添加失败写在了一个方法里。
- 使用pytest框架进行参数化(不仅可以对请求参数使用,也可以对响应数据参数化)。
- 该接口请求参数使用json格式。
python
'''
添加博客接口用例
'''
import pytest
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import read_yaml
class TestAdd:
url = host + "/blog/add"
schema = {
"type": "object",
"required": ["code","message","data"],
"additionalProperties": False,
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string","null"]
},
"data": {
"type": ["boolean","null"]
}
}
}
# 未登录状态
def test_add_nologin(self):
r = Request().post(url=self.url)
assert r.status_code == 401
# 登录状态 添加博客 ------ 添加成功+添加失败
@pytest.mark.parametrize("add",[
# 添加成功
{
"title":"接口自动化标题",
"content":"接口自动化内容",
"data":True
},
# 标题为空
{
"title": "",
"content": "接口自动化内容",
"data": None
},
# 内容为空
{
"title": "接口自动化标题",
"content": "",
"data": None
},
# 内容标题都为空
{
"title": "",
"content": "",
"data": None
},
# 添加图片
{
"title": "接口自动化------带有图片",
"content": "[](https://img95.699pic.com/photo/50053/4579.jpg_wh860.jpg)",
"data": True
},
# 添加带有链接的博客
{
"title":"接口自动化------带有链接",
"content":"[码云](https://gitee.com/java-flying \"码云\")",
"data":True
}
])
def test_add_login(self,add):
url = "http://localhost:8080/blog/add"
token = read_yaml("data.yml","user_token")
header = {
"user_token":token
}
json = {
"userId":read_yaml("data.yml","userId"),
"title":add["title"],
"content":add["content"]
}
r = Request().post(url=url,json=json,headers=header)
validate(r.json(),self.schema)
assert r.json()["data"] == add["data"]
5) 获取登录用户信息接口
- 该接口和获取博客详情接口类似,基本上是一样的,都是从yaml文件获取有效id,拼接到url请求路径上;使用json schema校验类型;assert断言校验关键数据;使用参数化多组用例执行。
python
import pytest
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import read_yaml
class TestGetUserInfo:
url = host + "/user/getUserInfo?userId="
schema = {
"type": "object",
"required": ["code","message","data"],
"additionalProperties": False,
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string","null"]
},
"data": {
"type": ["object","null"],
"required": ["id","userName","githubUrl"],
"additionalProperties": False,
"properties": {
"id": {
"type": "number"
},
"userName": {
"type": "string"
},
"githubUrl": {
"type": "string"
}
}
}
}
}
# 未登录状态下
def test_getUserInfo_nologin(self):
url = self.url + "1"
r = Request().get(url=url)
assert r.status_code == 401
# 登录状态下
# 有效的userId
def test_getUserInfo_login(self):
userId = read_yaml("data.yml","userId")
url = self.url + str(userId)
token = read_yaml("data.yml","user_token")
header = {
"user_token":token
}
r = Request().get(url=url,headers=header)
validate(instance=r.json(),schema=self.schema)
assert r.json()["code"] == 200
assert r.json()["data"]["id"] == userId
# 登录状态下
# 异常blogId
@pytest.mark.parametrize("userId",["",3,"abc",-100,9999999999999])
def test_getUserInfo_fail(self,userId):
params = {
"userId":userId
}
token = read_yaml("data.yml","user_token")
header = {
"user_token":token
}
r = Request().get(url=self.url,headers=header,params=params)
validate(r.json(),schema=self.schema)
assert r.json()["code"] == -2
6) 删除博客信息接口
- 该接口和获取博客详情以及登录用户信息接口基本一致,唯一不同的是该接口是post请求,及发送请求使用表单形式,其余相同,参考上面接口描述。
python
import pytest
from jsonschema.validators import validate
from utils.request_util import host, Request
from utils.yaml_util import read_yaml
@pytest.mark.order(7)
class TestDelete:
url = host + "/blog/delete"
schema = {
"type": "object",
"required": ["code","message","data"],
"properties": {
"code": {
"type": "number"
},
"message": {
"type": ["string","null"]
},
"data": {
"type": ["boolean","null"]
}
}
}
# 未登录下删除
def test_delete_nologin(self):
r = Request().post(url=self.url)
assert r.status_code == 401
# 登录状态下删除 ------ 正常删除
def test_delete_login(self):
token = read_yaml("data.yml","user_token")
header = {
"user_token":token
}
params = {
"blogId":read_yaml("data.yml","blogId")
}
r = Request().post(url=self.url,headers=header,params=params)
validate(r.json(),schema=self.schema)
# 登录状态下 ------ 异常删除
@pytest.mark.parametrize("blogId",["",3,"abc",2.5,-100,9999999999999])
def test_delete_fail(self,blogId):
token = read_yaml("data.yml", "user_token")
header = {
"user_token": token
}
params = {
"blogId": blogId
}
r = Request().post(url=self.url, headers=header, params=params)
validate(r.json(), schema=self.schema)
全代码参考码云仓库:【接口自动化 --- 个人博客系统】
六、执行测试用例
6.1 基础执行
直接在命令行执行pytest命令即可触发用例执行,执行示例日志:

当前自动化脚本执行成功,但是当没用指定用例执行顺序时也许会报错。当前执行顺序是按照文件和方法顺序进行执行的,执行通过是因为在数据文件中已经存在有效数据。

而当第一次执行时,因为有些数据必须要在登录和列表用例执行后才能得到,可能会发生错误,因此需要进行用例执行顺序的指定。
6.2 指定用例执行顺序
pytest本身不直接支持配置修改测试用例默认运行顺序,可通过pytest-order第三方插件实现,适用于存在用例依赖关系的场景。
- 安装插件
python
pip install pytest-order
- 使用方式:通过
@pytest.mark.order(数字)标记测试类/方法,数字越小执行顺序越靠前
python
@pytest.mark.order(1)
def test_one():
assert True
@pytest.mark.order(2)
def test_two():
assert True
- 执行结果:按标记顺序执行用例
七、生成测试报告并分析结果
7.1 测试报告生成
通过allure 的命令生成测试结果和测试报告,可以启动本地服务器实时查看报告,也可以生成静态的html文件,具体操作可查看该文:【测试结果可视化:Allure 在 Python 接口自动化中的应用】
生成的测试报告如下示例:


7.2 测试结果分析
- 测试时间:执行时间从19:43:37 持续到 19:43:43,总共耗时 6秒 42毫秒。测试时间与测试用例数量成正比,用例数量越多,测试时间越长;可通过优化测试脚本、并行执行和分布式测试环境缩短测试时间。
- 测试用例总数 :共有45个测试用例,高测试用例数 代表测试覆盖范围较广,能更全面地验证接口功能;低用例总数可能意味着测试覆盖不全面,存在遗漏风险。
- 通过率:45个测试用例全部通过,100%的通过率表示所有测试用例均成功执行,无失败用例。通过率是衡量接口质量和测试效果的关键指标,测试环境中通过率应达到95%以上。