新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python接口自动化测试实战:基于pytest与requests搭建苍穹外卖脚本

发布时间:2026/9/15 15:13:17来源:尧图网络
Python接口自动化测试实战:基于pytest与requests搭建苍穹外卖脚本
简介这是一套面向接口测试工程师及Python自动化测试学习者的苍穹外卖接口自动化测试脚本源码可直接用于外卖系统核心接口的功能、稳定性与回归验证。压缩包共38个文件核心为23个Python脚本负责测试用例、工具封装与统一入口5个XML和5个YAML配置分别管理环境与测试数据另含TXT说明、INI运行参数、JPG流程图及IDEA工程文件整体仅487KB目录划分清晰。目前已有472人学习或浏览。源码完整覆盖员工登录、订单、套餐等接口测试场景封装了请求处理、断言校验、MySQL操作、YAML读取和日志记录等模块并通过run_all.py一键串联全部用例。借助conftest.py与分层目录结构读者可深入理解接口自动化框架的设计思路也能快速替换测试数据或扩展新接口投入实际项目复用。1. 苍穹外卖这类接口自动化测试脚本为什么要用 Python 单独做一套苍穹外卖是一个典型的“管理端 用户端”双端业务系统接口数量多、状态流转复杂手工回归一遍要小半天。把接口自动化测试脚本独立于被测系统来做是这里最合适的落地方式被测系统用什么语言不重要接口协议、请求参数、响应结构才是测试脚本关心的。Python 在接口自动化测试这个领域生态完整pytest 的断言和参数化机制几乎就是为用例组织准备的requests 封装 HTTP 细节yaml 管数据allure 出报告整个脚本源码量控制在几百行内就能覆盖核心回归场景。下面按测试脚本设计的角度把目录划分、登录态处理、数据驱动、多环境切换和报告接入这些点逐一拆开适合正在做接口自动化测试脚本或想把手点用例转成可持续执行用例的测试开发、后端工程师。2. 用 pytest 与 requests 搭建接口自动化测试脚本工程接口自动化测试脚本不是把测试代码堆在一个文件里跑通就完了脚本源码要能长期维护必须先把工程边界划清楚。常见的做法是按“配置、数据、封装、用例、报告”五个层次拆拆完之后谁改业务参数、谁加新用例、谁调公共方法都不会撞车。2.1 接口自动化测试脚本的目录划分与依赖选型先看一套可以直接落地的目录结构takeout_api/ ├── config/ │ ├── env.yaml │ └── settings.py ├── data/ │ ├── dish_page.yaml │ └── order_submit.yaml ├── utils/ │ ├── http_client.py │ ├── log.py │ ├── token.py │ └── assert_utils.py ├── testcases/ │ ├── conftest.py │ ├── test_auth.py │ ├── test_dish.py │ └── test_order.py ├── reports/ ├── requirements.txt └── pytest.iniconfig 放环境地址和全局配置data 放接口测试数据utils 放 HTTP 封装、日志、token 获取、断言工具testcases 放用例文件reports 放 allure 输出。pytest.ini 里做最基础的配置[pytest] testpaths testcases log_cli true log_cli_level INFOtestpaths 指定 pytest 收集用例的目录log_cli_level 让测试运行时直接打印日志排查问题时不至于盲跑。依赖方面核心是 pytest、requests、pyyaml、allure-pytest、pytest-rerunfailures用一个 requirements.txt 装齐pytest requests pyyaml allure-pytest pytest-rerunfailures不锁版本号的好处是环境干净时直接拉最新稳定版项目成熟后再用 pip freeze 固化。这几个依赖的分工如下表依赖包在脚本里的作用pytest测试框架负责用例发现、执行、断言、fixturerequestsHTTP 客户端负责发送接口请求pyyaml读取 yaml 格式的测试数据allure-pytest生成 Allure 测试报告pytest-rerunfailures失败用例自动重跑2.2 用 requests 封装统一请求入口用例里最忌每个方法都写一遍 requests.request一旦接口返回格式变化或者需要统一加日志、统一加 token改动量会失控。封装一个 HttpClient把请求的拼装、发送、日志收敛到一个地方。# utils/http_client.py import logging import requests class HttpClient: def __init__(self, base_url, timeout10): self.base_url base_url self.timeout timeout self.session requests.Session() self.session.headers.update({Content-Type: application/json}) def set_token(self, token): self.session.headers.update({Authorization: fBearer {token}}) def request(self, method, path, **kwargs): url self.base_url path kwargs.setdefault(timeout, self.timeout) logging.info(f[HTTP] {method} {url}) if params in kwargs: logging.info(f[HTTP] params{kwargs[params]}) if json in kwargs: logging.info(f[HTTP] body{kwargs[json]}) resp self.session.request(method, url, **kwargs) logging.info(f[HTTP] status{resp.status_code} body{resp.text[:500]}) return resp def get(self, path, **kwargs): return self.request(GET, path, **kwargs) def post(self, path, **kwargs): return self.request(POST, path, **kwargs) def put(self, path, **kwargs): return self.request(PUT, path, **kwargs) def delete(self, path, **kwargs): return self.request(DELETE, path, **kwargs)set_token 单独成一个方法登录拿到 token 之后注入到 session 的 Header 里后续所有请求自动携带。request 统一打印请求行、参数、响应状态和截断的响应体出了问题先看日志就能定位大头。实际写用例时传参按 requests 的习惯来查询参数走 paramsJSON 体走 jsonmultipart 上传走 files。2.3 登录 token 的 fixture 设计与隔离苍穹外卖的接口分管理端和用户端两套鉴权登录接口返回 token 后所有业务接口都要带 Authorization。用 fixture 把 token 的获取和注入固定下来用例本身不关心登录细节。# testcases/conftest.py import pytest from utils.http_client import HttpClient from utils.token import get_token pytest.fixture(scopesession) def admin_client(): client HttpClient(http://localhost:8080) token get_token(base_urlhttp://localhost:8080, path/admin/login, usernameadmin, password123456) client.set_token(token) return clientscopesession 表示整个测试会话只创建一次 client也只登录一次避免每条用例都走一遍登录流程执行时间会被放大几十倍。get_token 内部其实就是一次 requests.post把响应的 data.token 取出来# utils/token.py import requests def get_token(base_url, path, username, password): resp requests.post(base_url path, json{username: username, password: password}, timeout10) resp.raise_for_status() data resp.json() assert data[code] 1, f登录失败: {data} return data[data][token]把 token 获取放在 fixture 里的另一个好处是后续接多用户场景时只要再加一个 user_client fixture配置不同的账号密码即可用例层面无感知。3. 苍穹外卖核心业务接口用例与 yaml 数据驱动框架搭好只是第一步测试脚本能不能反映业务回归场景取决于用例怎么组织。苍穹外卖的接口适合按“管理端后台操作 用户端下单链路”两条线来打每条线背后都有一串状态变更。3.1 接口清单梳理苍穹外卖这类工程常见的接口结构大致如下模块接口路径方法鉴权说明管理端登录/admin/loginPOST无返回管理员 token分类分页/admin/category/pageGET管理员 token查询分类列表新增分类/admin/categoryPOST管理员 token测试新增后分页条数加一菜品分页/admin/dish/pageGET管理员 token按名称、分类过滤新增菜品/admin/dishPOST管理员 token创建菜品订单查询/admin/orders/pageGET管理员 token按状态查询订单用户登录/user/loginPOST无传 code 换 token营业状态/user/shop/statusGET无查询店铺营业状态提交订单/user/order/submitPOST用户 token下单真正的执行顺序先做管理员登录拿后台 token做分类、菜品、套餐的增删查改再做用户端登录和下单下单数据反过来又能在管理端订单查询里验证。这样用例之间就生成了数据闭环而不是各测各的。3.2 用 yaml 做数据驱动与参数化接口测试数据一变用例源码不应该跟着改。把数据抽到 yaml 文件用 pytest 的参数化把每条数据变成一条用例是接口自动化测试脚本里最常用的数据驱动方式。下面是一组分页查询菜品的测试数据# data/dish_page.yaml - name: 分页查询菜品-第一页 path: /admin/dish/page method: GET params: page: 1 pageSize: 10 expected: code: 1 records: 10 - name: 分页查询菜品-keyword过滤 path: /admin/dish/page method: GET params: page: 1 pageSize: 10 name: 辣子鸡 expected: code: 1 records_positive: true用例文件里通过 parametrize 读取# testcases/test_dish.py import pytest import yaml from pathlib import Path with open(Path(__file__).parent.parent / data / dish_page.yaml, encodingutf-8) as f: dish_page_cases yaml.safe_load(f) pytest.mark.parametrize(case, dish_page_cases, idslambda c: c[name]) def test_dish_page(admin_client, case): resp admin_client.get(case[path], paramscase[params]) body resp.json() assert body[code] case[expected][code]parametrize 的 ids 参数让每条用例在报告里显示成 yaml 里的 name而不是 test_dish_page[case0] 这种看不懂的名字。读取路径用 Path(file).parent.parent 向上回溯到工程根目录避免在不同目录下执行 pytest 时找不到 data 文件。3.3 断言要断言业务结果不只断言 code 等于 1苍穹外卖这类业务系统有个特点接口 code 为 1 表示操作成功但成功不代表数据真的变了。比如新增分类返回码是 1还要再查一次分页列表确认它的 name 和 sort 已落库提交订单要拿返回的 orderId 去查管理端订单列表确认订单状态是“待接单”。def test_add_category_then_query(admin_client): payload { name: 冬阴功汤, type: 1, sort: 99, status: 1 } add_resp admin_client.post(/admin/category, jsonpayload) assert add_resp.json()[code] 1 page_resp admin_client.get(/admin/category/page, params{page: 1, pageSize: 100}) records page_resp.json()[data][records] created [r for r in records if r[name] 冬阴功汤] assert len(created) 1 assert created[0][sort] 99这样断言的是业务结果而不是请求结果能拦住“接口返回成功但数据没写进去”这类典型 bug。如果落库有延迟可以给查询断言加一点重试等待但不要一开始就 time.sleep后面第 5 章会说怎么处理。4. 接口自动化测试脚本的登录态保持、环境切换与重试封装单条用例跑通不难难的是整个测试脚本在长时间执行、多环境执行时还稳定。登录态什么时候刷新、环境怎么切、失败怎么重跑这几件事决定脚本能不能进 CI。4.1 fixture 作用域与 token 过期处理前面把 admin_client 设成 session 级这里有一个隐患一次 pytest 会话跑半小时token 如果只有 30 分钟有效期后面的用例会全部 401。处理方法有几种常见的是在请求层做一次兜底重放# utils/http_client.py def request(self, method, path, max_retry1, **kwargs): url self.base_url path kwargs.setdefault(timeout, self.timeout) resp self.session.request(method, url, **kwargs) if resp.status_code 401 and max_retry 0: logging.warning(401 触发重新登录) if self.refresh_token: self.set_token(self.refresh_token()) resp self.session.request(method, url, **kwargs) return resprefresh_token 是外部注入的回调函数HttpClient 不关心业务登录细节。检测到 401 时重新登录一次并重放原请求对调用方完全透明。也可以把 token 设成 module 级 fixture每个模块开始前重新登录一次适合测试用例量不多但断言较重的场景。优先推荐重放方案因为它只浪费一次请求而不是每次重新登录。fixture 各作用域的选择逻辑可以这样定scope生命周期适用场景session整个测试会话登录 token、全局 HTTP 客户端module单个测试模块模块内共享的预置数据class单个测试类类内共享状态function每条用例默认级别独立数据4.2 多环境配置与 pytest 命令行参数脚本设计要保证在本地、测试环境、预发布环境都能执行。常见做法是把环境地址抽到 config/env.yaml用 pytest 的命令行参数选环境# config/env.yaml test: base_url: http://localhost:8080 admin: username: admin password: 123456 prod: base_url: https://api.dinner.example.com admin: username: prod_admin password: prod_pass在 conftest.py 里注册 --env 参数# testcases/conftest.py import yaml import pytest def pytest_addoption(parser): parser.addoption(--env, actionstore, defaulttest, help运行环境: test/prod) pytest.fixture(scopesession) def admin_client(request): env request.config.getoption(--env) with open(config/env.yaml, encodingutf-8) as f: config yaml.safe_load(f)[env] client HttpClient(config[base_url]) token get_token(config[base_url], /admin/login, config[admin][username], config[admin][password]) client.set_token(token) return client执行时pytest --envtest或pytest --envprod即可。密码直接写在 yaml 里的做法只适合没有安全要求的项目正经团队会把密码放到 Jenkins 的凭据或 CI 变量里用os.getenv读取。4.3 失败重试与日志落盘配置接口自动化测试脚本在 CI 里就怕偶发网络抖动一次超时就让整个流水线飘红。pytest 生态里有成熟方案pytest-rerunfailures 负责重跑logging 负责把每次请求的出入参落盘。pytest testcases --reruns 2 --reruns-delay 1 --envtest--reruns 2 表示失败后最多再跑两次--reruns-delay 1 表示每次重试间隔 1 秒给网络恢复留时间。注意重试只对用例级生效重试期间 fixture 不会重新创建所以登录态依然有效。日志落盘在 conftest 里配置 handler# utils/log.py import logging def setup_logging(): logging.basicConfig( levellogging.INFO, format%(asctime)s %(levelname)s %(message)s, handlers[ logging.StreamHandler(), logging.FileHandler(reports/run.log, encodingutf-8) ] )在 conftest.py 的 pytest_sessionstart 里调用一次保证整个会话只初始化一次。有了日志文件CI 里失败就能直接看 run.log 里的请求和响应片段。5. Allure 报告接入 CI 与三个高频踩坑点接口自动化测试脚本做出来不是为了本地跑是要接进流水线。Allure 是这里最常用的报告方案pytest 集成非常省事。执行完生成结果目录再用命令行转成 HTMLpytest testcases --envtest --alluredirreports/allure-results allure generate reports/allure-results -o reports/allure-report --clean在用例里加 allure 特性可以让报告里的层级更好看import allure allure.epic(苍穹外卖接口自动化测试) allure.feature(菜品管理) allure.story(分页查询) def test_dish_page(admin_client, case): passepic/feature/story 三级结构对应报告里的分组适合团队按模块分配用例维护责任。Jenkins 里只要在构建步骤里执行上面两条命令再配一个 allure 插件指向 reports/allure-report 即可。最后说三个我实践里踩过的坑。第一个是别用裸 time.sleep 等待数据生效优先用轮询断言比如每秒查一次接口最多等 5 秒把等待时间压缩到真实需要的时间。第二个是新增类用例跑完要清理数据否则第二次执行时会出现“重名导致创建失败”常见做法是测试数据用时间戳作为后缀或者干脆在 teardown 里调删除接口。第三个是注意共享状态session 级 client 里如果某一个用例改动了公共请求头后面的用例会跟着变改头之前先记下来用完恢复。这三个坑在接口自动化测试脚本稳定性的坑位里排得最靠前处理掉之后基本就不会再被偶发问题打断。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

STM32寄存器驱动MAX31856热电偶测温:SPI初始化与温度计算 2026/9/15 16:01:29

STM32寄存器驱动MAX31856热电偶测温:SPI初始化与温度计算

简介:基于STM32F103ZET6与MAX31856的测温工程,以寄存器操作为主线,面向嵌入式初学者及工业温度测量开发者,专门解决热电偶数据采集、SPI接口配置和驱动移植等问题。资源压缩包约1.77MB,整体为STM32工程源码&#xff0c…

阅读更多 →
基于 Rube MCP 与 Composio 的 Page X 自动化实战:awesome-codex-skills 官方 Skill 全解析 2026/9/15 16:01:29

基于 Rube MCP 与 Composio 的 Page X 自动化实战:awesome-codex-skills 官方 Skill 全解析

基于 Rube MCP 与 Composio 的 Page X 自动化实战:awesome-codex-skills 官方 Skill 全解析 【免费下载链接】awesome-codex-skills A curated list of practical Codex skills for automating workflows across the Codex CLI and API. 项目地址: https://gitcod…

阅读更多 →
G6 v5.0.43图可视化性能与编辑能力深度解析 2026/9/15 16:01:29

G6 v5.0.43图可视化性能与编辑能力深度解析

简介:G6图可视化引擎v5.0.43是一款面向前端开发者与数据可视化工程师的应用工具,专注于关系型数据的图形化表达与交互分析,有效解决社交网络、组织架构、流程建模及网络拓扑等场景中关系不透明、结构难理解的问题。资源包共1992个文件&#x…

阅读更多 →
Loop:macOS 开源窗口管理器,径向菜单 + 预览框实用指南 2026/9/15 16:01:29

Loop:macOS 开源窗口管理器,径向菜单 + 预览框实用指南

Loop:macOS 开源窗口管理器,径向菜单 预览框实用指南 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop Loop 是一款免费开源的 macOS 窗口管理工具(GPLv3,…

阅读更多 →
抖音批量下载实战:单条到整站主页的完整上手指南 2026/9/15 16:01:29

抖音批量下载实战:单条到整站主页的完整上手指南

抖音批量下载实战:单条到整站主页的完整上手指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖…

阅读更多 →
博物馆无障碍Web应用:API网关+前端AI工程实践 2026/9/15 15:58:28

博物馆无障碍Web应用:API网关+前端AI工程实践

简介:本资源是一套面向前端开发者与无障碍交互产品设计者的博物馆APP开源实现,聚焦于利用API集成与人工智能技术提升展馆服务的智能化与包容性,特别适配残障人士等多元用户群体。项目以HTML、JavaScript和CSS为核心技术栈,辅以SVG…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞