Skip to content

070. 测试环境适配、公共工具与拦截器 ​

学习目标 ​

这一节继续完善测试和基础工具。

学完后,你应该能理解:

  • 如何判断当前代码是否运行在 PyTest 环境;
  • Redis 工具类为什么要区分测试和生产;
  • 覆盖率报告怎么看;
  • 用 Agent 生成测试时为什么仍要人工校验;
  • 认证中间件和公共函数如何为通用模块做准备。

判断测试环境 ​

项目里需要一个函数判断当前是否在自动化测试环境。

一种简单方式是检查:

py
sys.modules

如果里面已经加载了 pytest,就说明当前进程大概率由 PyTest 启动。

这个判断可以用来切换少量测试专用逻辑。

例如 Redis 连接处理。

Redis 测试适配 ​

正式服务运行时,Redis 工具类可以复用连接池。

测试运行时,每个异步用例可能有自己的事件循环。

如果继续复用绑定旧事件循环的连接池,后面可能出现连接失效或事件循环关闭的问题。

所以 Redis 工具类可以这样处理:

  • 非测试环境使用连接池;
  • 测试环境创建独立客户端;
  • 使用结束后关闭客户端连接。

这样测试更稳定。

也不影响正式服务的性能策略。

覆盖率报告 ​

跑完整测试后,会生成覆盖率报告。

报告会告诉你:

  • 总覆盖率;
  • 每个文件的覆盖率;
  • 哪些行没有跑到;
  • 哪些分支缺少测试。

例如某个文件覆盖率是 92%,点进去可以看到剩下 8% 是哪些行。

这能指导后续补测试,而不是凭感觉补。

用 Agent 生成测试 ​

可以让 Agent 帮忙生成测试用例。

但生成结果不能直接信。

它可能:

  • 读错项目结构;
  • 写错导入路径;
  • 断言字段不对;
  • 忽略缓存或数据库状态;
  • 生成很长但无效的代码。

所以更合理的方式是让它先写初稿,再由开发者运行、删改、补断言。

测试最终要以运行结果和业务语义为准。

测试用例命名 ​

PyTest 里函数名不能重复。

如果两个测试函数同名,后面的可能覆盖前面的。

测试文件、测试函数都要有清晰命名。

例如:

py
def test_user_cache_gets_lisi():
    ...

def test_user_cache_gets_zhangsan():
    ...

这样报告里也更容易定位失败点。

AGENTS.md 的作用 ​

AGENTS.md 可以放项目级说明。

Agent 工具处理项目时,会优先读取这类说明。

适合写:

  • 测试要求;
  • 代码风格;
  • 目录约定;
  • 模块边界;
  • 生成测试时必须遵守的规则。

也可以在具体模块下放更细的说明文件。

例如 Redis 模块有自己的开发说明,通用模块也有自己的开发说明。

这样 Agent 在处理特定模块时能拿到更准确的上下文。

认证中间件补充 ​

认证中间件需要区分 Token 类型。

例如 API 路由应该要求 API Token。

普通登录接口应该要求访问 Token。

如果不区分,可能出现用错 Token 类型也能访问接口的问题。

这类逻辑适合放在中间件里统一处理,而不是每个接口单独判断。

call 公共函数 ​

通用模块会支持类似拦截器的能力。

例如新增前、新增后、更新后执行某个函数。

这些函数接收的参数不一定完全一样。

有的只需要 row。

有的需要 row 和 session。

有的还需要 user。

call 公共函数的作用是:

  • 读取目标函数签名;
  • 从上下文里挑出它需要的参数;
  • 多余参数不传;
  • 如果是异步函数就 await;
  • 如果是同步函数就直接执行。

这能让拦截器写法更灵活。

雪花 ID 与路径拼接 ​

项目还补充了几个基础工具。

雪花 ID 用来生成纯数字 ID。

它不依赖数据库函数,适合某些需要数字编号的场景。

路径拼接工具要处理:

  • 多余斜杠;
  • 末尾斜杠;
  • http 和 https 开头的地址;
  • 普通相对路径。

这些工具看起来小,但会被通用模块反复调用。

BasicSchema ​

BasicModel 面向数据库表实体。

它包含 ID、创建时间、更新时间等字段。

但有些请求参数或响应参数不直接参与数据库增删改查。

这类结构更适合继承 BasicSchema。

命名上可以这样区分:

  • Model 表示数据库实体;
  • Schema 表示请求或响应结构。

这个区分能减少后续类型混乱。

这一节的重点 ​

这一节是在给通用模块铺底层能力。

你需要记住:

  • 测试环境和正式环境可以有少量基础设施差异;
  • Redis 连接池要注意事件循环生命周期;
  • Agent 生成测试后必须运行和校验;
  • Token 类型应该在中间件统一校验;
  • call 函数让同步和异步拦截器共用一套执行方式;
  • Model 和 Schema 要按是否参与数据库实体来区分。

AI Agent 课程学习文档。