(二十五)再启动一次真实进程
TestClient 能方便地检查应用,但它没有走实际的监听端口、命令入口和进程启动。交付前再执行一段冒烟检查:临时启动 Uvicorn,通过真正 HTTP 请求完成一条主要操作。
# 项目文件:catalog_project/tools/check.py
from pathlib import Path
import subprocess
import sys
# 先检查业务规则,再用真实的本机 HTTP 请求检查启动过程。
root = Path(__file__).resolve().parents[1]
subprocess.run([sys.executable, "-m", "pytest", "-q"], cwd=root, check=True)
subprocess.run([sys.executable, "tools/smoke.py"], cwd=root, check=True)两个项目都有相同的检查入口。sys.executable 指向当前运行工具的解释器,所以子进程继续使用这套环境;subprocess.run(..., check=True) 在前一步失败时停止后续步骤。smoke.py 使用随机可用本机端口和临时目录,最后结束服务进程。
# 书目项目:测试后执行真实采集、查询、备份和新路径恢复。
uv run python tools/check.py
# 模型项目也执行同一命令:临时训练、启动服务、比较 CLI 与 API。
完整实现见 书目冒烟检查 和 模型冒烟检查。它们用 try/finally 管理服务生命周期;Windows 中结束这次启动的整棵子进程树,避免解释器入口退出后还有服务器占着端口。
本章还实际用两个 Uvicorn 工作进程核对重开查询、发布新版本、重开载入和回退。检查结果保存在 核验记录,便于对照操作结果。