FlowCheck 项目全景|一次接口回归怎样从配置走到报告

本文依据 FlowCheck 的源码和本地验证记录整理,写作使用了 AI 辅助。

创建文章的接口返回了 201,查询接口也返回了 200,读出来的标题却和写进去的不一样。要在下一次改代码后重新检查这件事,还得登录取令牌、创建文章、记下文章 ID、查询核对,再删除测试数据。这些请求单独调通之后,整条业务流程仍值得重复验证。

我做的 FlowCheck 是一个面向个人开发者的 HTTP 接口回归测试平台。它把请求顺序、检查规则和跨步骤传递的变量保存为用例。每次改完代码,可以选一个环境重新跑同一套用例,看看哪一步失败、当时的响应是什么、实际值和期望值差在哪里。当前项目处于早期开发阶段,已经用内置的文章服务验证了从配置、真实发请求到保存报告的链路。

整体架构

浏览器经 Nginx 访问页面和 API。FastAPI 接受配置与运行请求,先把任务写进 PostgreSQL。独立的 Dispatcher 读出待派发任务,通过 Redis 把运行 ID 交给 Celery Worker。Worker 请求被测服务,把步骤结果和进度事件存回 PostgreSQL。浏览器从 API 读取报告和事件。

组件 用了什么 在 FlowCheck 里做什么
Web Vue 3、TypeScript、Vite、Element Plus、Nginx Vue 负责用例编辑器、运行列表和报告页,TypeScript 约束接口数据结构,Vite 构建前端,Element Plus 提供表单和表格。Nginx 提供构建后的页面,把 /api/ 请求转发到后端,并对 SSE 路径关闭缓冲,让事件可以及时到达浏览器。
API FastAPI、Uvicorn、Pydantic、SQLAlchemy、asyncpg FastAPI 提供登录、项目配置、任务提交、报告和事件接口,由 Uvicorn 运行。Pydantic 校验传入的数据,SQLAlchemy 管理数据库模型和事务,API 通过异步驱动 asyncpg 访问 PostgreSQL。
数据库迁移 Alembic 按版本创建和更新平台的数据库结构。Compose 启动时先完成迁移,再启动 API、Worker 和 Dispatcher。
派发进程 Python、SQLAlchemy、psycopg Dispatcher 定期读取数据库里的待派发记录,把运行 ID 发到 Redis。它也会检查长时间没有被领取或没有结束的运行,并更新状态。
后台执行 Celery、HTTPX、SQLAlchemy、psycopg Celery Worker 领取任务,读出快照,用 HTTPX 按顺序请求被测服务,再把检查结果写回数据库。执行放在后台后,提交接口可以先把运行 ID 返回给浏览器。
平台数据库 PostgreSQL 保存用户、项目、接口定义、环境和用例,也保存运行快照、步骤结果、进度事件和待派发记录。历史报告从这里读取。
消息与缓存 Redis 在执行链路中充当 Celery 的消息中转站,暂存待执行的任务。项目概览也用 Redis 做短期缓存,统计数据来自 PostgreSQL。
被测服务 FastAPI、SQLite 文章 Demo API 提供登录、创建、查询和删除接口,作为 Worker 的真实 HTTP 请求目标。它用独立的 SQLite 库存放演示文章。

本地使用 Docker Compose 管理这些服务。Compose 把容器连在同一个网络里,配置启动依赖和持久化数据卷,并把 Web、API 文档和 Demo API 的入口映射到本机。用例执行过程和报告读取都可以用这套本地环境演示。

Compose 服务定义 · 架构说明

从项目配置到五步用例

在 FlowCheck 里,环境回答「向哪里发请求,用什么配置」,用例回答「按什么顺序发请求,怎样算通过」,运行是选定一个环境执行一次用例所产生的记录。项目把这些配置和历史结果归在一起。

  1. 登录并创建项目。 注册或登录 FlowCheck 后,在「我的项目」中新建项目。平台按项目所有者校验资源访问权限。FlowCheck 的登录账号用于管理项目,五步用例里的登录请求则使用 Demo API 的账号。

  2. 配置测试环境。 在「环境配置」中选择部署允许的目标地址,再填写环境变量和公共请求头。以文章 Demo 为例,环境可以提供登录步骤所需的账号和密码。敏感值加密保存,编辑页面回读时只显示是否已设置。

  3. 按需导入接口定义。 可以在「接口定义」中上传 OpenAPI 3.0 或 3.1 的 JSON 文件。OpenAPI 文件描述接口的方法、路径和参数等信息。选中导入的定义可以预填步骤里的请求字段,实际业务值、鉴权和检查规则仍由编写用例的人确定。也可以直接手动添加步骤。

  4. 编排用例。 在「测试用例」中新建用例,按业务顺序添加 HTTP 请求。每一步都有一条状态码断言,还可检查 JSON 字段值或响应耗时是否符合预期。需要跨步骤传值时,可以用提取器从响应中读取字段并命名,后面的步骤通过 {{变量名}} 引用。

  5. 提交运行。 在「运行记录」点击「执行用例」,选择用例和环境。提交成功后进入运行报告页,查看运行进度和最终结果。

仓库预置了「文章回归五步」,用来演示两个值怎样在请求之间传递。

顺序 请求 检查与变量传递
1. 登录 POST /auth/login 检查 200,从 $.access_token 提取 auth_token,并标记为敏感值。
2. 创建文章 POST /articles 携带 Bearer {{auth_token}},用 smoke-{{run_id}} 作为标题。检查 201,从响应提取 article_id。
3. 查询文章 GET /articles/{id} 用 {{article_id}} 查询同一篇文章,检查 200,并核对 $.title 是否等于创建时使用的标题。
4. 删除文章 DELETE /articles/{id} 删除这次运行创建的文章,检查 204。
5. 再次查询 GET /articles/{id} 再查同一个 ID,预期返回 404。

第 5 步的 404 是通过条件,因为这一步验证的是文章已被删除。第 3 步则同时检查状态码和标题,所以返回 200 仍可能触发断言失败。

五步用例的种子脚本

点下执行之后,后台怎样处理这次运行

1. 冻结输入并创建运行记录

前端向 POST /api/v1/projects/{project_id}/runs 提交用例 ID、环境 ID,并携带一个 Idempotency-Key。同一项目内,用同一个键重试相同的用例和环境 ID 会返回已有运行;用同一个键提交另一组参数会收到 409。主动再执行一次会使用新的键。

API 检查项目归属,读取当前的用例和环境版本,把目标地址、环境变量、公共请求头、步骤定义和执行限制打包成一份加密的运行快照。这次运行固定使用提交时的输入,之后对用例或环境的编辑会在下一次新运行中生效。

接着,API 在一个 PostgreSQL 事务里写入四类记录。

记录 初始内容
运行 运行 ID、用例与环境版本、加密快照,状态为 queued
步骤结果 按顺序预建每一步的记录,状态为 pending
进度事件 写入第一条 run.queued
Outbox 记下一条待派发任务,状态为 pending

数据库提交成功后,API 返回 202 Accepted 和运行 ID。此时浏览器就可以打开报告页,查看这次运行的排队状态。

2. 派发任务并由 Worker 领取

Outbox 可以理解为数据库里的待发清单。创建运行和登记待发任务属于同一个事务,因此即使 API 提交后 Redis 暂时不可用,数据库里仍然有记录可供 Dispatcher 继续处理。

Dispatcher 找到可以发送的记录后,通过 Redis 投递携带 run_id 的 Celery 任务。若投递失败,它会保留待发记录并延迟下一次尝试。若同一条消息被重复投递,Worker 通过 PostgreSQL 的一次条件更新争抢执行权。只有仍处于 queued 且未过排队期限的运行,才能被其中一个 Worker 切换到 running 并领取。

3. 逐步执行请求,保存脱敏结果

Worker 根据运行 ID 取得快照,解密后为这次运行建立独立的变量上下文。以第 2 步创建文章为例,它把第 1 步提取的令牌填入请求头,把本次运行 ID 填入文章标题,再向 Demo API 发送请求。

收到响应后,Worker 检查断言并读取配置了提取规则的字段。只有步骤通过,提取值才会交给后续步骤使用。创建步骤通过后,article_id 就能用于查询和删除。请求的目标受允许列表约束,执行器也对请求超时和响应大小设有限制。

每一步的状态、耗时、脱敏的请求和响应摘要、断言结果与提取结果写入 PostgreSQL,同时记录对应的进度事件。报告中可以看出令牌已被提取,具体令牌值会被遮蔽。遇到失败时,本次运行结束,尚未执行的步骤标为 skipped。

4. 通过事件追踪进度,再读取最终报告

报告页先读取已有的运行记录。运行仍在进行时,页面通过 SSE(Server-Sent Events)接收服务器发送的进度事件,例如开始运行、开始某一步、完成某一步。API 从 PostgreSQL 按事件 ID 读取,连接中断后,浏览器可以带着最后收到的 ID 接着读。多次连接失败时,页面改为定期查询报告。

收到 run.finished 后,页面请求最终报告。进度事件负责告诉页面发生了什么变化,完整的步骤结果和脱敏预览则由报告接口读取。刷新报告或回看历史时,页面读取的是已有运行记录。

运行提交代码 · 任务派发代码 · 用例执行器 · 事件流代码

失败时能看到什么

情况 运行结果 接下来发生什么
五步都满足断言 passed 报告保留五步的检查结果。
查询返回 200,标题检查失败 failed 报告指出第 3 步的标题断言失败,第 4、5 步被跳过。
变量未定义、请求发生网络错误或提取失败 error 报告记录具体错误和所在步骤,后续步骤跳过。
排队超时仍无人领取 error 派发进程结束这次运行,并记录派发超时。
执行超时或 Worker 中途退出 interrupted 报告提示部分写操作可能已生效,用户可先检查目标服务中的数据。

下面这份报告来自一个故意改错标题期望值的演示。查询的状态码断言通过,标题断言失败。此时创建文章已经成功,删除步骤没有执行,测试文章可能留在 Demo 数据库里。Outbox 的重试只负责投递任务;对已经开始的业务 HTTP 请求,FlowCheck 不会自动重放。

五步通过报告 · 故障演示与复现步骤 · 已有实测记录

在本地跑一遍

准备 Python 3.12 和 Docker Compose v2。先克隆 FlowCheck,再在仓库根目录生成环境文件并启动服务。已有本地 .env 的话,从 Compose 命令开始。

git clone https://github.com/xyyyyi-x/flowcheck.git
cd flowcheck
python scripts/init_env.py
docker compose up --build -d
docker compose ps

等服务启动并通过健康检查后,准备演示数据并提交一次运行。

python scripts/seed_demo.py
python scripts/smoke.py

正常情况下,smoke 会打印 run_status=passed 和五步的状态。也可以打开 http://127.0.0.1:8080,使用本地 .env 中的 PLATFORM_DEMO_USERNAME 和 PLATFORM_DEMO_PASSWORD 登录。进入「文章回归 Demo」,在「运行记录」里选择「Compose Demo」环境和「文章回归五步」用例,从报告中查看每个步骤的结果。

项目启动说明 · API 与用例定义契约

posted @ 2026-11-10 11:52  我不明白-  阅读(0)  评论(0)    收藏  举报