Monorepo 测试架构
面向同时包含前端、BFF、微服务和 AI agent 的 monorepo,组织测试层次、共享质量资产、CI 分层和运行反馈闭环的测试架构。
#type / synthesis
#status / growing
#tech / dev / test
[!info] related notes
- 所属 MOC: Testing MOC, 项目实践 MOC
- 相关概念: 软件测试基础, Monorepo 测试中的共享质量资产
- 相关主题: 契约测试与 CDC, Agent 测试与评估, 发布与运行期验证, Nx
Monorepo 测试架构
范围
这篇笔记讨论的是一个同时包含前端、BFF、微服务和 AI agent 的 monorepo,应该如何组织完整测试体系。
为什么要放在一起理解
这类仓库最大的风险不是“测试框架选错”,而是:
- 各层测试没有分工
- 所有验证都挤到 E2E
- 契约、fixture、eval 数据集散落在各项目里
- CI 每次全仓全量跑,反馈慢到没人愿意等
所以这类仓库需要的不是更多零散测试,而是一套能跨项目、跨层次协作的测试架构。
一个典型示例仓库
repo/
├─ apps/
│ ├─ web/
│ └─ bff/
├─ services/
│ ├─ order-service/
│ ├─ payment-service/
│ └─ notification-service/
├─ agents/
│ └─ support-agent/
├─ packages/
│ ├─ ui/
│ ├─ domain-order/
│ ├─ sdk/
│ ├─ contracts/
│ ├─ prompts/
│ ├─ evals/
│ └─ testkit/
├─ infra/
│ ├─ docker/
│ ├─ k8s/
│ └─ smoke/
└─ .github/workflows/
总体策略
这类仓库不应该追求“所有测试都一样重”,更合理的策略是:
- 大量快速小测试
- 少量更宽的系统测试
也就是:
- domain / component / handler / tool wrapper 这些地方追求高频快速反馈
- contract / integration / workflow / release 验证只保留高价值覆盖
时间轴视角
1. 需求与方案
先定义:
- 用户主旅程
- 失败路径
- 非功能预算
- 服务边界契约
- agent eval seed set
这一层是在为未来的测试提供 test basis,而不是先写脚本。
2. 架构与仓库基建
这一层先把基础设施搭出来:
packages/contractspackages/testkitpackages/evals- CI
- ephemeral env
- observability
3. 功能开发内循环
这一层是 TDD 和快速反馈的主战场:
packages/domain-*apps/web组件测试apps/bffhandler testsservices/*service / domain testsagents/*tool wrapper / router / prompt rendering tests
4. 边界与集成
这里重点补:
- 数据库集成测试
- HTTP contract tests
- 事件 schema compatibility
- 第三方 sandbox tests
5. 系统验证
只保留少量高价值测试:
- Web 关键旅程
- 跨服务工作流
- agent scenario evals
6. 发布与运行反馈
继续补:
- smoke
- canary
- shadow
- rollback verification
- production incidents -> regression / eval growth
空间视角
Release / Runtime
Workflow / System
Boundary / Integration
Fast tests
Static gates
Shared quality assets
这个视角的重点是:测试不是单一金字塔,而是多层系统。真正把各层串起来的,是底部的共享质量资产。
共享质量资产为什么是脊柱
在这类仓库里,最容易被低估的不是测试脚本,而是:
packages/contractspackages/testkitpackages/evals
如果它们不是一等公民,测试体系会很快碎成各服务各写一套、各 agent 各藏一份。
各目录怎么测
apps/web
- 组件测试
- 页面与容器交互
- 关键旅程 E2E
apps/bff
- request validation
- auth / permission
- orchestration
- consumer-side contract tests
services/*
- 领域规则
- 状态机
- 幂等
- outbox / event publish
- DB integration
agents/*
- deterministic unit
- stubbed workflow tests
- trace grading
- dataset evals
- shadow / canary
一个具体功能怎么贯穿全仓库
拿“退款流程”举例:
- 需求层先定义成功路径、失败路径、幂等、超时和 agent 限制
packages/domain-order里用 TDD 写退款规则apps/bff用 consumer contract 固化它对 order-service 的假设services/order-service用 integration test 验证 DB + eventagents/support-agent用 router unit tests + eval dataset 验证“不能在信息不足时直接承诺成功”apps/web只保留少量关键旅程 E2E
这比“把所有逻辑都塞给 UI 测试”更稳,也更便宜。
CI 怎么分层
PR 层
- static
- fast tests
- affected boundary tests
- selective smoke
Nightly 层
- full unit + integration
- 全量 contract verification
- 关键旅程 E2E
- 全量 agent eval
- 性能与安全扫描
Release 层
- staging smoke
- deploy verification
- rollback verification
- canary
- synthetic monitors
三条关键触发规则
改 packages/contracts/**
必须触发:
- contract tests
- provider verification
- compatibility checks
改 agents/** / packages/prompts/** / packages/evals/**
必须触发:
- deterministic tests
- eval smoke
- representative dataset eval
- 发布期 shadow / canary
改 infra/**
必须触发:
- smoke
- synthetic checks
- rollback rehearsal
常见坑
- 只有 unit + e2e,两层之间没有 integration / contract
- agent 只靠人工聊天试一试,没有 eval 体系
- PR 每次全仓全量跑
- prompt 和 contract 不版本化
最短记忆方式
Monorepo 测试架构不是一个框架,而是一套分层反馈系统;它的脊柱是 contracts、testkit 和 evals。