← 返回文章列表

测试通过了,为什么演示数据反而被污染

复盘 TeachFlow 从共享测试库转向一次性 PostgreSQL、动态端口与职责分离 Golden 数据的根因修复。

返回 TeachFlow 项目总览

有一类测试失败最隐蔽:终端显示绿色,产品页面也能打开,但教师工作台里突然多了测试学生、孤儿作业或异常掌握度。脚本证明了自己能写,却破坏了下一次演示要使用的事实。

TeachFlow 曾经让多条回归复用共享开发数据库,并依赖 seed 和清理顺序恢复现场。随着课堂、作业、Evidence、Current、Outbox 和 Neo4j 投影越来越多,这个假设终于失效。

最小失败链

预期行为:回归构造测试事实、完成断言、退出后不影响共享演示数据。

实际风险:脚本中途异常,或者清理遗漏 append-only 子记录;下次 seed 只补缺失数据,不会知道哪些残留属于失败测试;Golden Demo 又把共享库当作权威样本,最终出现“测试通过、演示不可信”。

受影响的不只是页面整洁,而是三类结论:

  • 班级人数和证据覆盖不再可信;
  • 恢复演练可能在外键孤儿上失败;
  • 不同任务并行时会互相改变基线。

根因不是“清理脚本少删了一张表”

增加更多 DELETE 可以暂时止血,却没有恢复不变量。真正被破坏的合同是:普通回归不应该拥有共享演示事实的生命周期。

共享测试库与隔离回归的对比

Playwright 官方文档把测试隔离定义为每个测试在独立 clean-slate 环境运行,从而避免失败传递并提高可复现性。浏览器上下文解决 cookies、storage 等客户端状态;TeachFlow 需要把同一原则延伸到数据库、图库、端口和上传资产。

修复落在最早的权威层

常规 classroom-learning-loop:check 现在由包装器先创建一次性 PostgreSQL 和一次性 Neo4j,执行完整 migration,分配动态空闲端口,再启动当前 production build。测试完成或子脚本异常退出时,父进程负责销毁临时数据环境。

这个改动恢复了几个关键不变量:

  • 普通回归写入只能存在于任务拥有的数据库;
  • 并行检查不争用固定端口;
  • 测试夹具、图片字节和投影随临时环境一起消失;
  • 脚本不能依赖前一个脚本留下的课程或 Session;
  • Smoke 必须显式导入自己要检查的内容。

Golden 数据没有被一刀切删除

隔离并不意味着所有测试都要使用同一种数据库。

demo:golden-check 的职责是证明共享 seed 之后那条固定演示链仍然成立,因此它必须在明确的共享演示库上运行;PostgreSQL 恢复演练也必须针对当前发布源库做 dump/restore。普通回归则不允许借用这些状态。

这是一条容易忽略的经验:测试隔离不是把所有环境都临时化,而是让每个入口只拥有自己职责所需的状态。

修复之后暴露出的真实问题

当回归不再依赖共享步骤顺序,一些之前被遮住的错误反而出现了:

  • 某些脚本没有准备自己的 Publication;
  • Smoke 在空库里绿色,却实际上少测了课程数据;
  • replica 清理顺序留下孤儿外键,直到 pg_restore 才失败;
  • 大分页游标把 PostgreSQL 微秒截成 JavaScript 毫秒,10,005 道题偶发只返回 10,004 道。

这说明隔离的价值不只是“保持干净”,它还迫使测试声明自己的前置条件。

为什么不能只看 HTTP 200

一个健康接口返回 200,只能证明当前请求成功。它不能证明数据库没有残留、浏览器完成真实动作、跨班授权被拒绝、备份可以恢复,或异常退出后资源被清理。TeachFlow 因此把类型、数据库合同、production 浏览器、恢复和 Golden seed 拆成不同证据层。

当前证据边界

项目记录表明隔离回归曾覆盖双班 Publication/Session/Board/Assignment/Evidence/Materialization 和浏览器恢复;本文固定快照未附带新的完整发布门禁,也没有当前机器的容器资源审计。本文可以说明修复机制与历史发现,不能把历史 21 步回执描述成当前运行结果,更不能推出学校生产并发。

常见问题与设计边界

为什么不用事务回滚代替临时数据库?
浏览器、多个 HTTP 请求、Worker、Neo4j 与子进程跨越单一事务边界;临时数据库为整条链提供更清晰的生命周期。

每次建库会不会太慢?
会增加成本,所以快速类型/lint 与全栈隔离检查分层运行。速度不能靠复用不可信状态换取。

如何防止异常退出留下资源?
父进程持有资源清单,在 finally 和信号处理路径清理;最终仍要审计实际运行集合,不能只相信退出日志。

参考资料

结论

测试污染不是“测试数据不好看”,而是测试越过了自己的状态所有权。TeachFlow 的 durable fix 不是继续加清理分支,而是让普通回归从创建到销毁都拥有独立环境,同时保留 Golden 和恢复演练各自真实职责。绿色结果只有不改变被测基线,才值得信任。

← 返回文章列表