Skip to content

测试指南

本文档介绍了 IAM 项目中引入的自动化测试体系。我们采用了 Vitest 进行单元和组件测试,以及 Playwright 进行端到端(E2E)测试,并通过 Turborepo 实现了全栈测试的统一编排。

项目采用分布式测试策略,针对不同层级的代码选用最合适的工具:

层级 工具选型 目标 路径
后端单元/集成测试 Vitest 测试 Hono API 路由、tRPC Logic、Utils apps/server/src/*.test.ts
前端组件测试 Vitest + RTL 测试 UI 组件渲染与交互逻辑 apps/web/src/**/*.test.ts(x)
共享包测试 Vitest 认证、契约、数据库、API 路由与工具函数 packages/*/src/*.test.ts
端到端测试 (E2E) Playwright 模拟真实用户在浏览器中的核心业务链路 apps/web/e2e/*.spec.ts

Terminal window
pnpm env:check

该命令检查本地 .dev.vars 是否存在、必填项格式和企业微信配置组是否完整,但不会输出任何密钥值。

在项目根目录下,可以通过一个命令运行所有子项目的单元与组件测试:

Terminal window
pnpm test

[!NOTE] 该命令通过 Turborepo 运行所有配置了 test 脚本的 workspace,包括 apps/server、apps/web 以及 packages 下的 api、auth、contracts、db、env。

改单个包时优先跑窄范围测试,比全仓库更快也更少受本机资源影响:

Terminal window
pnpm --filter @IAM/auth test
pnpm --filter server test
pnpm --filter web test

共享包(如 @IAM/contracts)改动会影响多个应用,这类变更应再跑一次 pnpm test 确认。

Terminal window
pnpm test:e2e

[!TIP] Playwright 会自动启动 apps/web 的 Next.js 服务。需要真实认证后端的用例仍需确保 8787 API 可用,并正确配置 AUTH_UPSTREAM_URL。


后端使用 Vitest 的 node 环境执行。

  • tRPC 集成测试:我们推荐使用 tRPC 的 createCaller 模式。这种模式不需要启动真实的 HTTP 服务,而是直接在进程内调用路由逻辑,执行速度极快且能够深度覆盖权限检查、数据库交互等业务。
  • Hono 请求测试:利用 Hono 实例自带的 .request() 方法,可以直接模拟 Fetch API 风格的请求来验证 REST 路由。

前端使用 Vitest 的 jsdom 环境,结合 React Testing Library (RTL)。

  • 环境 Mock:我们在 vitest.setup.ts 中配置了常用的浏览器 API Mock(如 matchMedia, ResizeObserver),并集成了 jest-dom 断言库。
  • TypeScript 支持:项目已配置项目级类型定义,在 .test.tsx 文件中可直接获得 describe, it, expect 的智能补全。
  • 配置文件:apps/web/playwright.config.ts
  • 可视化调试:执行 pnpm --filter web test:e2e:ui 可打开 Playwright 的交互式界面,支持断点调试、时光倒流追踪(Trace Viewer)等功能,极大提升 E2E 编写效率。test:e2e:ui 只定义在 apps/web,根目录没有同名脚本。

项目接入了 v8 覆盖率引擎。分别执行:

Terminal window
pnpm --filter server test:coverage
pnpm --filter web test:coverage
pnpm --filter @IAM/auth test:coverage

运行结束后,可分别在 apps/server/coverage、apps/web/coverage 和 packages/auth/coverage 查看报告。packages 下的其余包(api、contracts、db、env)也都配置了同名 test:coverage 脚本。


  1. 测试文件命名:
    • 单元测试请以 .test.ts 或 .test.tsx 结尾,并与源代码放在同级目录。
    • E2E 测试请统一存放在 apps/web/e2e/ 目录下。
  2. 避免过度 Mock:在 tRPC 测试中,建议尽量真实调用底层 Service,仅对外部网络请求或极其复杂的模块进行 Mock。
  3. CI 集成:.github/workflows/ci.yml 已分三个 job 执行完整门禁——静态检查(pnpm lint、pnpm format:check、pnpm check-types)、Vitest(pnpm test)与 Playwright(pnpm test:e2e)。本地提交前至少运行 pnpm check 与受影响包的测试。

已有测试覆盖 Hono 路由、OIDC 负例、数据库 batch、R2 上传、企微登录、认证默认配置、前端登录与 OAuth 客户端表单。上线前仍需优先补:

  • 完整 Authorization Code + PKCE 正流程
  • refresh token rotation、重放和撤销
  • 邮箱验证、密码重置与旧会话失效 E2E
  • 企微离职禁用、通讯录回调和全量同步异常
  • 应用角色、用户/部门授权与 app_role claim 一致性

pnpm test:e2e 会启动 apps/server/e2e/server.ts,使用每次重建的内存 PostgreSQL(PGlite)及固定测试账号,不读取本地 .dev.vars。测试账号仅在该测试进程存在,启动入口拒绝非 test 环境。端口 8787 必须空闲,避免浏览器用例误连已有后端;前端使用 3000 端口。

浏览器回归覆盖管理员登录与应用列表、普通用户页面和 API 拒绝访问,以及原生资料更新的部门字段保护。协议层的完整授权码、刷新及撤权回归位于 apps/server/src/oauth-flow.test.ts。

PGlite 的 runDbBatch 使用真实数据库事务执行,批次后续失败必须回滚前面的写入。packages/db/src/batch-rollback.test.ts 与 packages/auth/src/provisioning-outbox.test.ts 覆盖事务回滚、审计失败、任务重试及并发新任务保护;它们不代表已验证线上 Neon 的网络与性能行为。

CI 另外执行 API Worker 的 wrangler deploy --dry-run 和 OpenNext Worker 生产构建,均不发布线上资源。