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

有的需要 rowsession

有的还需要 user

call 公共函数的作用是:

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

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

雪花 ID 与路径拼接

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

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

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

路径拼接工具要处理:

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

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

BasicSchema

BasicModel 面向数据库表实体。

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

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

这类结构更适合继承 BasicSchema

命名上可以这样区分:

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

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

这一节的重点

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

你需要记住:

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

AI Agent 课程学习文档。