CI 中的测试策略分层smoke、integration 与 e2e 的执行时机CI 里跑全量 e2e 测试要 45 分钟——每次提交都跑开发者等得比写代码还久。一、场景痛点你的 CI 流程在每次 push 时跑全量测试500 个单元测试2 分钟 200 个集成测试10 分钟 50 个 e2e 测试45 分钟。总耗时 57 分钟。开发者一天提交 10 次累计等待 570 分钟9.5 小时——比实际工作时间还长。核心矛盾不是所有测试都需要在每次提交时跑——smoke 测试每次跑快集成测试合并时跑中等e2e 测试发布前跑慢。二、底层机制与原理剖析2.1 测试金字塔与执行时机2.2 smoke 测试的定义smoke 不是跑几个单元测试而是验证系统核心功能是否可用的精选子集核心业务流程登录→下单→支付5 个 e2e关键 API 可达性/health、/api/v1/status10 个集成核心单元测试数据校验、认证逻辑50 个单元总计约 65 个耗时 3-5 分钟三、生产级代码实现3.1 GitHub Actions 分层测试配置# .github/workflows/test-tiered.yaml —— 分层测试 CI 配置 name: Tiered Test Pipeline on: push: branches: [*] # 每次 push 跑 smoke pull_request: branches: [main] # PR merge 跑 unit integration workflow_dispatch: # 手动触发全量 e2e jobs: # Tier 1: smoke 测试 — 每次 push 触发3-5 分钟 smoke: runs-on: ubuntu-latest if: github.event_name push steps: - uses: actions/checkoutv4 - name: Install dependencies run: npm ci - name: Run smoke tests run: npm run test:smoke # test:smoke 脚本只跑精选的 65 个关键测试 # 脚本定义在 package.json # test:smoke: jest --testPathPatternsmoke/ --maxWorkers4 # Tier 2: 单元 集成测试 — PR merge 触发12 分钟 unit-integration: runs-on: ubuntu-latest if: github.event_name pull_request steps: - uses: actions/checkoutv4 - name: Install dependencies run: npm ci - name: Run unit tests run: npm run test:unit - name: Run integration tests run: npm run test:integration # 集成测试需要数据库用 Docker 启动临时数据库 - name: Setup test database run: docker-compose -f docker-compose.test.yaml up -d db - name: Run integration tests run: npm run test:integration - name: Teardown test database if: always() run: docker-compose -f docker-compose.test.yaml down # Tier 3: 全量 e2e 测试 — 发布前手动触发45 分钟 e2e-full: runs-on: ubuntu-latest if: github.event_name workflow_dispatch steps: - uses: actions/checkoutv4 - name: Setup full test environment run: docker-compose -f docker-compose.test.yaml up -d - name: Run e2e tests run: npm run test:e2e # e2e 测试跑在完整环境中所有服务 真实数据库 # 超时设置单个 e2e 测试最长 5 分钟 env: TEST_TIMEOUT: 300000 - name: Teardown if: always() run: docker-compose -f docker-compose.test.yaml down3.2 smoke 测试精选脚本// jest.smoke.config.ts —— smoke 测试配置只跑关键路径 export default { // 只跑 smoke 目录下的测试 testPathPattern: smoke/, // 并行执行4 个 worker 加速 maxWorkers: 4, // 超时单个 smoke 测试最长 10 秒 testTimeout: 10000, // 失败策略第一个失败就停止smoke 测试失败 核心功能不可用 bail: 1, }; // smoke/api-health.test.ts —— API 可达性 smoke 测试 describe(API Smoke Tests, () { test(Health endpoint is reachable, async () { const response await fetch(${API_URL}/health); expect(response.status).toBe(200); }); test(Core API v1 status endpoint, async () { const response await fetch(${API_URL}/api/v1/status); expect(response.status).toBe(200); }); test(Authentication endpoint works, async () { const response await fetch(${API_URL}/api/v1/auth/login, { method: POST, body: JSON.stringify({ username: test, password: test }), }); expect(response.status).toBeLessThan(500); // 不期望 500 错误 }); }); // smoke/core-flow.test.ts —— 核心业务流程 smoke 测试 describe(Core Business Flow Smoke, () { test(Login → Create Order → Pay flow, async () { // Step 1: 登录 const loginRes await fetch(${API_URL}/api/v1/auth/login, { method: POST, body: JSON.stringify({ username: smoke_test, password: smoke_pass }), }); const { token } await loginRes.json(); expect(token).toBeDefined(); // Step 2: 创建订单 const orderRes await fetch(${API_URL}/api/v1/orders, { method: POST, headers: { Authorization: Bearer ${token} }, body: JSON.stringify({ product_id: smoke-product, quantity: 1 }), }); const { order_id } await orderRes.json(); expect(order_id).toBeDefined(); // Step 3: 支付 const payRes await fetch(${API_URL}/api/v1/payments, { method: POST, headers: { Authorization: Bearer ${token} }, body: JSON.stringify({ order_id, method: mock }), }); expect(payRes.status).toBeLessThan(500); }); });四、边界分析与架构权衡4.1 smoke 测试的覆盖盲区smoke 只验证核心流程不验证边界条件并发冲突、数据校验、异常恢复。如果核心流程通过但边界条件有 bugsmoke 不会发现。对策smoke 是快速兜底不是完整验证。完整验证靠集成测试和 e2e 测试。smoke 的目标是在 3 分钟内告诉你核心功能是否还活着。4.2 e2e 测试的脆弱性e2e 测试依赖完整环境环境问题数据库重启、网络抖动会导致测试失败但不是代码 bug。e2e 测试的失败率约 5-10% 是环境问题不是应用问题。对策e2e 测试失败后自动重试一次。如果重试仍失败人工排查是否是环境问题。4.3 适用边界与禁用场景适用日提交 5 次、团队 3 人、测试总量 200 个禁用日提交 2 次等 57 分钟也没关系、测试总量 50 个全量跑也很快、紧急修复时跳过 e2e 直接发布五、结语CI 测试策略的核心是分层执行smoke 每次 commit 跑3-5 分钟集成测试 PR merge 时跑12 分钟e2e 发布前跑45 分钟。开发者日常等待时间从 57 分钟降到 3-5 分钟。smoke 不是跑几个测试而是验证核心功能是否可用的精选子集——5 个核心 e2e 10 个 API 可达性 50 个关键单元测试。e2e 测试只在发布前跑不在每次提交时跑。e2e 的环境脆弱性用自动重试缓解。分层策略的前提是测试总数量足够多200 个否则全量跑也很快。资料说明本文中的协议、版本、性能、成本和行业趋势应以可核验的一手资料为准。未标注统计口径的比例、时间表和预测仅作工程讨论不应视为行业事实。可参考 0730 资料来源索引并在发布前将具体来源贴到对应断言之后。