shift-left-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<objective> Move quality validation earlier in the development lifecycle where defects are cheaper, faster, and simpler to fix. A missing validation rule caught in refinement is a five-minute conversation; the same bug in production is an incident, a hotfix, and a postmortem. This skill covers the practices, patterns, and cultural shifts that embed quality into every phase — from story refinement to PR merge — plus a maturity model to find the next concrete step. </objective>
<objective> 将质量验证前移至开发生命周期中更早的阶段,在此阶段发现缺陷的修复成本更低、速度更快、难度更小。在需求细化阶段发现缺失的验证规则,只需要五分钟的沟通;而在生产环境中发现同样的bug,则会引发事故、紧急修复和事后复盘。本技能涵盖了将质量嵌入从需求细化到PR合并每个阶段的实践、模式和文化转变,同时提供成熟度模型以确定下一步具体行动。 </objective>

Quick Route

快速指引

SituationGo to
QA only sees features after dev is "done"Dev/QA Pairing → QA in Sprint Planning
Need a pre-dev requirements conversationDev/QA Pairing → Three Amigos Sessions
Deciding whether to TDD this workTDD Facilitation → When TDD vs. Test-After
Reviewing a PR for test qualityPR Review Checklist
Reviewing an AI-generated/AI-using PRPR Review Checklist → When the Change Is AI-Generated
"Where is my team and what's next?"Shift-Left Maturity Model

场景参考内容
QA仅在开发“完成”后才接触功能Dev/QA结对 → QA参与迭代规划
需要在开发前进行需求沟通Dev/QA结对 → Three Amigos会议
决定是否对该项工作采用TDDTDD引导 → TDD vs. 事后测试决策指南
评审PR的测试质量PR评审清单
评审AI生成/使用AI的PRPR评审清单 → 当变更由AI生成时
“我的团队处于什么阶段,下一步该怎么做?”左移成熟度模型

Discovery Questions

探索性问题

Check
.agents/qa-project-context.md
first — if it exists, use it (team composition, dev/QA workflow, sprint structure, quality goals) and skip anything answered there.
首先查看
.agents/qa-project-context.md
——如果该文件存在,使用其中的信息(团队构成、Dev/QA工作流程、迭代结构、质量目标),并跳过已解答的问题。

Current Dev/QA Workflow

当前Dev/QA工作流程

  1. When does QA first see a feature? After PR is raised? After merge to staging? Only when a bug appears? The answer reveals how far right your quality currently sits.
  2. Who writes tests, and when? Developers only? QA only after dev is "done"? Both but on different timelines? Understanding current ownership is essential before changing it.
  3. How are requirements communicated? Written specs? Verbal handoffs? Figma links with no acceptance criteria? Ambiguous requirements are the #1 source of defects that shift-left prevents.
  4. Is there interest in TDD? Has the team tried it before? Did it stick or collapse? Understanding past attempts prevents repeating failed approaches.
  5. What does the PR review process look like? Who reviews? Is testability a review criterion? Are tests required before merge? PR review is the lowest-friction place to introduce quality checks.
  6. What is the team's Definition of Done? Written or unwritten? Does it include testing? Is it enforced or aspirational? The DoD is the contractual boundary between "in progress" and "done."
  7. How does QA participate in sprint planning? Not at all? Consulted on estimates? Actively refining stories? Sprint planning participation determines how early QA thinking enters the cycle.

  1. QA首次接触功能的时间点? PR提交后?合并到预发布环境后?仅当bug出现时?答案会揭示你的质量验证当前处于生命周期的多么靠后的位置。
  2. 谁负责编写测试,何时编写? 仅开发人员?仅QA在开发“完成”后编写?双方都写但时间线不同?在改变现状前,必须了解当前的职责划分。
  3. 需求如何传递? 书面规格说明?口头交接?只有Figma链接且无验收标准?模糊的需求是左移要预防的头号缺陷来源。
  4. 团队对TDD是否感兴趣? 是否尝试过TDD?坚持下来了还是中途放弃?了解过往尝试可以避免重复失败的方法。
  5. PR评审流程是怎样的? 谁负责评审?可测试性是否是评审标准?合并前是否要求必须有测试?PR评审是引入质量检查的最低摩擦环节。
  6. 团队的完成定义(DoD)是什么? 书面还是口头约定?是否包含测试要求?是强制执行还是仅作为目标?DoD是“进行中”和“已完成”之间的契约边界。
  7. QA如何参与迭代规划? 完全不参与?仅参与估算咨询?积极参与需求细化?QA在迭代规划中的参与程度决定了QA思维何时进入开发周期。

Core Principles

核心原则

1. Quality Is Everyone's Responsibility

1. 质量是所有人的责任

Quality is not a phase performed by the QA team after development. It is a property of the entire workflow: product managers write testable requirements, developers write tests alongside code, code reviewers check for testability, and QA engineers design the strategy and catch what automation misses. When quality belongs to everyone, defects are caught by whoever encounters them first.
质量不是开发完成后由QA团队执行的一个阶段,而是整个工作流程的固有属性:产品经理编写可测试的需求,开发人员在写代码的同时编写测试,代码评审人员检查可测试性,QA工程师设计测试策略并捕捉自动化测试遗漏的问题。当质量成为所有人的责任时,缺陷会被第一个遇到它的人发现。

2. Earlier Detection = Cheaper Fixes (Directionally)

2. 越早发现缺陷,修复成本越低(总体趋势)

A missing validation rule caught during story refinement is a five-minute conversation. The same defect found in production is an incident, a hotfix, a postmortem, and eroded user trust. The cost of fixing a defect rises sharply the further right it is caught — refinement < design < development < QA < staging < production. That direction is real and well-attested; the exact multipliers are not. The widely cited "1x → 100x" table traces to an undated, unsourced IBM Systems Science Institute training chart with no published methodology, so treat any precise figure as illustrative, not measured. Lead with the concrete cost story above, not invented numbers. Shift-left practices aim to catch defects in the cheap left-hand columns — refinement through development — before QA, staging, or prod ever see them.
在需求细化阶段发现缺失的验证规则,只需要五分钟的沟通。同样的缺陷在生产环境中被发现,则会引发事故、紧急修复、事后复盘,还会损害用户信任。缺陷被发现的阶段越靠后,修复成本就越高——细化阶段 < 设计阶段 < 开发阶段 < QA阶段 < 预发布阶段 < 生产阶段。这个趋势是真实且经过验证的;具体的成本倍数则无需纠结。广泛引用的“1倍→100倍”成本表源自一份未标注日期、无来源的IBM系统科学研究院培训图表,没有公开的方法论,因此任何精确数字都仅作说明,而非实测数据。优先使用上述具体的成本案例,而非虚构的数字。左移实践旨在将缺陷拦截在成本较低的左侧阶段——从细化到开发阶段——在QA、预发布或生产环境接触之前。

3. QA Is Embedded, Not a Gate

3. QA是嵌入式角色,而非门禁

Traditional QA acts as a gate at the end of development: code is "thrown over the wall" for testing. Shift-left embeds QA throughout the process. QA contributes to story refinement, pairs with developers on test design, reviews PRs for testability, and validates early through continuous testing. The gate model creates bottlenecks and adversarial dynamics. The embedded model creates collaboration and shared ownership.
传统QA在开发结束时充当门禁:代码被“扔过墙”进行测试。左移则将QA嵌入整个流程。QA参与需求细化、与开发人员结对设计测试、评审PR的可测试性,并通过持续测试提前验证。门禁模式会造成瓶颈和对立关系,而嵌入式模式则促进协作和共同责任。

4. Testability Is a Design Concern

4. 可测试性是设计考量因素

Code that is hard to test is usually hard to maintain, hard to debug, and likely to contain defects. Testability should be a first-class design constraint alongside performance, security, and usability. When developers ask "how will we test this?" during design -- before writing a single line of code -- the resulting architecture is cleaner, more modular, and more reliable.
难以测试的代码通常也难以维护、调试,且更可能包含缺陷。可测试性应与性能、安全性、易用性一样,成为首要设计约束。当开发人员在设计阶段——甚至在写第一行代码之前——就问“我们如何测试这个?”时,最终的架构会更简洁、更模块化、更可靠。

5. Start Small, Prove Value, Then Expand

5. 从小处着手,证明价值后再扩展

Introducing every shift-left practice simultaneously overwhelms teams. Pick one practice (usually PR review checklists or Three Amigos), prove its value with data (fewer bugs escaping, faster PR cycles), then use that success to justify the next practice. Cultural change happens one demonstrated win at a time.

同时引入所有左移实践会让团队不堪重负。选择一个实践(通常是PR评审清单或Three Amigos会议),用数据证明其价值(更少的逃逸bug、更快的PR周期),然后用这个成功案例来证明下一个实践的合理性。文化变革是通过一次次已验证的胜利逐步实现的。

Dev/QA Pairing Patterns

Dev/QA结对模式

QA in Sprint Planning

QA参与迭代规划

What it looks like: QA engineers attend sprint planning and actively participate in story refinement. They ask clarifying questions about edge cases, identify missing acceptance criteria, and flag risk areas before development begins.
Concrete actions during planning:
  1. Review each story for testable acceptance criteria. Every acceptance criterion should be verifiable -- "user can sort the table" is testable; "table is user-friendly" is not.
  2. Identify edge cases and negative scenarios. What happens with empty data? Max length input? Concurrent users? Network failure mid-operation?
  3. Flag integration risks. Does this story touch a third-party API? Does it change database schema? Does it affect existing test data?
  4. Estimate QA effort. Automation time, exploratory testing time, environment setup. Include this in sprint capacity.
  5. Define test approach per story. Unit tests for business logic, integration tests for API changes, E2E for user-facing flows.
Template: QA questions for each story
Story: [PROJ-1234] Add coupon code to checkout
───────────────────────────────────────────────
QA questions before development starts:
1. What happens if the coupon is expired?
2. What happens if the coupon is already used (single-use)?
3. Can multiple coupons be stacked?
4. What error message does the user see for invalid codes?
5. Does the discount update the total in real-time or on submit?
6. Is there a rate limit on coupon validation attempts?

Test approach:
- Unit: coupon validation logic, discount calculation, expiry check
- Integration: coupon API endpoint, database state after redemption
- E2E: apply coupon in checkout flow, verify discount on confirmation
- Exploratory: edge cases with currency rounding, max discount limits
具体形式: QA工程师参与迭代规划并积极参与需求细化。他们就边缘情况提出澄清问题,识别缺失的验收标准,并在开发开始前标记风险区域。
规划期间的具体行动:
  1. 评审每个需求的可测试验收标准。每个验收标准都应可验证——“用户可以对表格排序”是可测试的;“表格易于使用”则不可测试。
  2. 识别边缘情况和负面场景。空数据会发生什么?输入最大长度会怎样?并发用户操作?操作中途网络故障?
  3. 标记集成风险。该需求是否涉及第三方API?是否修改数据库 schema?是否影响现有测试数据?
  4. 估算QA工作量。自动化测试时间、探索性测试时间、环境搭建时间。将这些纳入迭代容量规划。
  5. 为每个需求定义测试方法。业务逻辑用单元测试,API变更用集成测试,用户面向流程用E2E测试。
模板:每个需求的QA问题
Story: [PROJ-1234] Add coupon code to checkout
───────────────────────────────────────────────
QA questions before development starts:
1. What happens if the coupon is expired?
2. What happens if the coupon is already used (single-use)?
3. Can multiple coupons be stacked?
4. What error message does the user see for invalid codes?
5. Does the discount update the total in real-time or on submit?
6. Is there a rate limit on coupon validation attempts?

Test approach:
- Unit: coupon validation logic, discount calculation, expiry check
- Integration: coupon API endpoint, database state after redemption
- E2E: apply coupon in checkout flow, verify discount on confirmation
- Exploratory: edge cases with currency rounding, max discount limits

Three Amigos Sessions

Three Amigos会议

A structured 15-30 minute conversation between three perspectives before development begins.
The three perspectives:
  • Product/Business: What does the user need? Why does this matter?
  • Development: How will we build it? What are the technical constraints?
  • QA/Testing: How will we verify it? What could go wrong?
Optional fourth amigo (AI participant): A coding agent can generate edge cases and counter-scenarios from the acceptance criteria mid-session. Treat AI output as a checklist to validate, not a decision — humans still own the criteria.
Session format (30 minutes max):
  1. Product presents the story (5 min) -- user need, acceptance criteria
  2. Development asks clarifying questions (5 min) -- feasibility, dependencies
  3. QA asks testing questions (5 min) -- edge cases, error states, testability
  4. Group identifies gaps (10 min) -- missing criteria added, assumptions made explicit
  5. Agreement and next steps (5 min) -- updated story, risks documented, test approach agreed
When to use: Stories with risk score Medium+, anything touching payments/auth/data integrity, stories with ambiguous requirements, cross-team stories.
When to skip: Simple bug fixes with clear repro steps, copy/text-only changes, dependency updates with no behavioral change.
开发开始前,三个视角的人员进行15-30分钟的结构化对话。
三个视角:
  • 产品/业务方: 用户需要什么?这件事为什么重要?
  • 开发方: 我们如何实现?技术约束是什么?
  • QA/测试方: 我们如何验证?可能会出什么问题?
可选的第四个Amigo(AI参与者): 编码Agent可以在会议中根据验收标准生成边缘情况和反场景。将AI输出视为需要验证的清单,而非决策依据——人类仍拥有标准的最终决定权。
会议格式(最多30分钟):
  1. 产品方介绍需求(5分钟)——用户需求、验收标准
  2. 开发方提出澄清问题(5分钟)——可行性、依赖关系
  3. QA方提出测试相关问题(5分钟)——边缘情况、错误状态、可测试性
  4. 团队共同识别缺口(10分钟)——补充缺失的标准、明确假设
  5. 达成共识并确定下一步(5分钟)——更新需求、记录风险、商定测试方法
适用场景: 风险等级为中等及以上的需求、涉及支付/认证/数据完整性的需求、需求模糊的需求、跨团队需求。
不适用场景: 有明确复现步骤的简单bug修复、仅涉及文案/文本的变更、无行为变更的依赖更新。

QA Pairing on Test-First Design

QA结对进行测试先行设计

QA and developer collaborate on test cases before implementation. This is not full TDD -- it is test thinking applied collaboratively.
How it works:
  1. Developer and QA sit together (or share screen) for 20-30 minutes
  2. QA describes the scenarios they plan to test
  3. Developer writes the test signatures (function names, inputs, expected outputs)
  4. Together they identify which tests are unit, integration, and E2E
  5. Developer implements the feature with these tests as the target
Example output from a pairing session: a set of agreed test signatures spanning unit, integration, and E2E levels, written before implementation. See
references/tdd-examples.md
for the full coupon-feature pairing output.
QA与开发人员在实现前协作设计测试用例。这不是完整的TDD——而是协作应用测试思维。
操作方式:
  1. 开发人员和QA一起(或共享屏幕)工作20-30分钟
  2. QA描述他们计划测试的场景
  3. 开发人员编写测试签名(函数名、输入、预期输出)
  4. 双方共同确定哪些测试是单元测试、集成测试和E2E测试
  5. 开发人员以这些测试为目标实现功能
结对会话的示例输出: 一套涵盖单元、集成和E2E级别的商定测试签名,在实现前编写完成。完整的优惠券功能结对输出请参见
references/tdd-examples.md

QA Reviewing PRs

QA评审PR

QA engineers review pull requests with a focus on testability and test quality, complementing the code review performed by other developers.
Getting started for teams new to QA PR reviews:
  1. Start with one QA reviewer on high-risk PRs only. Do not try to review every PR on day one.
  2. Time-box reviews to 15 minutes. QA is checking for test quality, not re-reviewing business logic.
  3. Use the PR Review Checklist below. It provides concrete, objective criteria -- no subjective judgment required.
  4. Leave comments as suggestions, not demands. Frame as "Consider adding a test for the empty state" rather than "Missing tests."
  5. Track value. Note when QA review catches a gap. After 2-4 weeks, share the count with the team to demonstrate ROI.

QA工程师从可测试性和测试质量的角度评审拉取请求,补充其他开发人员的代码评审。
对于刚引入QA PR评审的团队,入门步骤:
  1. 从仅让一名QA评审高风险PR开始。不要第一天就尝试评审所有PR。
  2. 将评审时间限制在15分钟内。QA只检查测试质量,不重新评审业务逻辑。
  3. 使用下面的PR评审清单。它提供了具体、客观的标准——无需主观判断。
  4. 将评论作为建议而非要求。表述为“考虑添加空状态的测试”而非“缺少测试”。
  5. 跟踪价值。记录QA评审发现的缺口。2-4周后,与团队分享统计数据以证明投资回报率。

TDD Facilitation

TDD引导

Red-Green-Refactor

红-绿-重构

TDD follows a strict three-step cycle. Each step has a clear purpose and a clear exit condition.
┌──────────────────────────────────────────────────────┐
│  RED: Write a failing test                           │
│  - Test describes the desired behavior               │
│  - Test MUST fail (if it passes, it tests nothing)   │
│  - Write the minimum test to specify one behavior    │
│                                                      │
│  GREEN: Make the test pass                           │
│  - Write the minimum code to pass the test           │
│  - No extra features, no premature optimization      │
│  - It is OK if the code is ugly                      │
│                                                      │
│  REFACTOR: Clean up                                  │
│  - Improve code structure without changing behavior  │
│  - All tests still pass after refactoring            │
│  - Remove duplication, improve naming, simplify      │
└──────────────────────────────────────────────────────┘
Example: TDD for a password strength validator — first failing test, minimum passing code, then a behavior-preserving refactor into a rules array. See
references/tdd-examples.md
for the full Red-Green-Refactor walk-through.
TDD遵循严格的三步循环。每个步骤都有明确的目的和退出条件。
┌──────────────────────────────────────────────────────┐
│  RED: Write a failing test                           │
│  - Test describes the desired behavior               │
│  - Test MUST fail (if it passes, it tests nothing)   │
│  - Write the minimum test to specify one behavior    │
│                                                      │
│  GREEN: Make the test pass                           │
│  - Write the minimum code to pass the test           │
│  - No extra features, no premature optimization      │
│  - It is OK if the code is ugly                      │
│                                                      │
│  REFACTOR: Clean up                                  │
│  - Improve code structure without changing behavior  │
│  - All tests still pass after refactoring            │
│  - Remove duplication, improve naming, simplify      │
└──────────────────────────────────────────────────────┘
示例:密码强度验证器的TDD实践——先编写失败测试,再编写最小可行通过代码,然后进行行为不变的重构,将逻辑整理为规则数组。完整的红-绿-重构流程请参见
references/tdd-examples.md

When TDD vs. Test-After: Decision Guide

TDD vs. 事后测试:决策指南

TDD is not always the right choice. Use this guide to decide.
ScenarioApproachWhy
Pure business logic (validators, calculators, transformers)TDDClear inputs/outputs, fast feedback, tests document behavior
Bug fix with known reproductionTDDWrite failing test first = proof the fix works
API endpoint with clear contractTDDRequest/response is a natural test boundary
Exploratory UI prototypingTest-afterDesign is unstable; tests would rewrite constantly
Third-party integrationTest-afterNeed to understand the API behavior first
Complex data migrationTest-after with fixturesWrite sample data first, then test transformation
Performance optimizationTest-after with benchmarksNeed baseline before testing improvement
AI-generated implementationTDD (test first)LLMs happily produce passing-looking code; the failing test is the spec the agent must satisfy. Highest-leverage check on AI output.
TDD并非总是正确选择。使用本指南进行决策。
场景方法原因
纯业务逻辑(验证器、计算器、转换器)TDD输入输出清晰,反馈快速,测试可记录行为
有已知复现步骤的bug修复TDD先编写失败测试=证明修复有效
有明确契约的API端点TDD请求/响应是天然的测试边界
探索性UI原型开发事后测试设计不稳定,测试会频繁重写
第三方集成事后测试需要先了解API行为
复杂数据迁移带测试数据的事后测试先编写示例数据,再测试转换逻辑
性能优化带基准测试的事后测试需要先有基准线再测试优化效果
AI生成的实现TDD(测试先行)LLM会生成看似可行的代码;失败测试是Agent必须满足的规范。这是对AI输出最高效的检查方式。

TDD for Bugs (The Litmus Test)

针对bug的TDD(试金石)

Every bug fix should start with a failing test that reproduces the bug. This practice provides three guarantees:
  1. You understand the bug. If you cannot write a test that fails, you do not understand the bug.
  2. The fix actually works. The test turns green when the fix is applied.
  3. The bug never returns. The test stays in the suite as a regression guard.
See
references/tdd-examples.md
for a worked failing-test-first example (a JPY zero-decimal rounding bug).
每个bug修复都应从编写一个能复现bug的失败测试开始。这个实践提供三个保证:
  1. 你理解了bug。如果你无法编写一个失败的测试,说明你还不理解bug。
  2. 修复确实有效。修复后测试会变为绿色。
  3. bug不会再次出现。测试会留在测试套件中作为回归防护。
完整的“先写失败测试”示例(日元零小数位舍入bug)请参见
references/tdd-examples.md

Kata Exercises for Teams Learning TDD

团队学习TDD的Kata练习

Short exercises (30-60 min) to build TDD muscle memory:
KataDifficultyKey lesson
FizzBuzzBeginnerBasic Red-Green-Refactor cycle
String CalculatorBeginnerIncremental complexity, edge cases
Roman NumeralsIntermediatePattern recognition, refactoring
Bowling GameIntermediateState management, complex rules
Gilded RoseAdvancedRefactoring legacy code under test harness
Format: Pair programming, 45 minutes, switch driver every 5 minutes. Debrief for 15 minutes: what was hard? What felt natural? What would you do differently?

短练习(30-60分钟)以建立TDD肌肉记忆:
Kata难度核心要点
FizzBuzz入门基础红-绿-重构循环
String Calculator入门增量复杂度、边缘情况
Roman Numerals中级模式识别、重构
Bowling Game中级状态管理、复杂规则
Gilded Rose高级在测试 harness下重构遗留代码
形式: 结对编程,45分钟,每5分钟切换驾驶员。15分钟复盘:哪里难?哪里感觉自然?下次会怎么做?

PR Review Checklist: QA Perspective

PR评审清单:QA视角

Use this checklist when reviewing PRs for test quality and testability. Not every item applies to every PR -- use judgment based on the change scope.
使用本清单从测试质量和可测试性角度评审PR。并非每个条目都适用于所有PR——根据变更范围判断。

Tests Exist and Are Meaningful

测试存在且具备实际意义

  • Tests accompany the code change. New feature? New tests. Bug fix? Regression test. Refactor? Existing tests still pass (and ideally improve). No-test PRs for behavioral changes need explicit justification.
  • Both happy path and edge cases are covered. At minimum: valid input, invalid input, empty/null input, boundary values. For user-facing features: error states, loading states, empty states.
  • Tests describe behavior, not implementation. Test names read as specifications:
    rejects expired coupon with clear error message
    not
    test coupon validator function line 42
    .
  • 测试与代码变更同步提交。新增功能?新增测试。修复bug?添加回归测试。重构?现有测试仍能通过(理想情况下还能优化)。涉及行为变更的无测试PR需要明确的理由。
  • 覆盖了正常路径和边缘情况。至少包括:有效输入、无效输入、空/Null输入、边界值。对于用户面向功能:错误状态、加载状态、空状态。
  • 测试描述行为而非实现。测试名称应像规格说明:
    rejects expired coupon with clear error message
    而非
    test coupon validator function line 42

Code Is Testable

代码具备可测试性

  • Functions have clear inputs and outputs. Pure functions are trivially testable. Functions with side effects should isolate the side effect (dependency injection, wrapper functions).
  • Dependencies are injectable. Database clients, HTTP clients, clocks, and random number generators should be parameters or injected -- not imported directly inside business logic.
  • No hardcoded magic values. Constants are named and configurable. Test can override them without modifying production code.
  • 函数有清晰的输入和输出。纯函数易于测试。有副作用的函数应隔离副作用(依赖注入、包装函数)。
  • 依赖可注入。数据库客户端、HTTP客户端、时钟、随机数生成器应作为参数或注入——而非直接在业务逻辑中导入。
  • 无硬编码魔法值。常量应命名且可配置。测试无需修改生产代码即可覆盖这些值。

Test Quality

测试质量

  • Selectors use stable strategies. E2E tests use
    data-testid
    ,
    getByRole
    , or
    getByLabel
    -- not CSS classes or XPath. See the selector stability scoring in
    test-reliability
    .
  • Assertions are specific.
    expect(result).toEqual({ status: 'expired', code: 'COUPON_EXPIRED' })
    not
    expect(result).toBeTruthy()
    .
  • Test data is deterministic. No dependency on current date, random values, or auto-increment IDs without explicit control. Use factories or fixtures.
  • Tests clean up after themselves. Created records are deleted. Modified state is restored. No test pollution.
  • Test names describe the scenario. A reader unfamiliar with the code should understand what is being tested from the test name alone.
  • No coverage-only tests. Tests that execute code without meaningful assertions inflate coverage without providing safety.
  • 选择器使用稳定策略。E2E测试使用
    data-testid
    getByRole
    getByLabel
    ——而非CSS类或XPath。请参见
    test-reliability
    中的选择器稳定性评分。
  • 断言具体明确
    expect(result).toEqual({ status: 'expired', code: 'COUPON_EXPIRED' })
    而非
    expect(result).toBeTruthy()
  • 测试数据可确定。不依赖当前日期、随机值或自动递增ID,除非有明确控制。使用工厂或测试数据模板。
  • 测试完成后清理自身。删除创建的记录,恢复修改的状态。无测试污染。
  • 测试名称描述场景。不熟悉代码的读者应能仅从测试名称理解测试内容。
  • 无仅为覆盖率的测试。仅执行代码但无有意义断言的测试会虚增覆盖率,却无法提供防护。

When the Change Is AI-Generated or AI-Using

当变更由AI生成或使用AI时

Apply these additional checks when a PR contains code authored by an AI agent or introduces an AI-powered feature.
  • AI provenance disclosed. PR description names the agent, model, and what it generated (so reviewers calibrate scrutiny appropriately).
  • Tests written first or by a human. AI-generated implementation paired with AI-generated tests is a closed loop — at least one side of the test/implementation pair should be authored or critically reviewed by a human (see TDD decision guide row above).
  • Prompt and model version pinned. For AI-using features (LLM calls, prompt templates), the prompt version and model ID live in a flag-based config store — LaunchDarkly AI Configs (GA 2025) or equivalent — not embedded as ad-hoc strings that drift. The PR should reference the config key, not paste the prompt inline.
  • Runtime kill switch wired. Any AI feature ships behind a feature flag that can disable it without redeploy. Pair shift-left prevention with shift-right containment.
  • Prompt eval test exists. At least one regression test for the prompt's behavior on representative inputs (see
    ai-system-testing
    ).
  • No fabricated APIs or imports. Reviewer verifies every imported symbol exists — LLMs invent plausible-sounding APIs.

当PR包含AI Agent编写的代码或引入AI驱动的功能时,需额外进行以下检查。
  • AI来源已披露。PR描述中注明Agent、模型以及生成内容(以便评审者调整审查力度)。
  • 测试由人类编写或先行编写。AI生成的实现搭配AI生成的测试是闭环——测试/实现对中至少有一方应由人类编写或严格评审(参见上述TDD决策指南)。
  • 提示词和模型版本已固定。对于使用AI的功能(LLM调用、提示词模板),提示词版本和模型ID应存储在基于标志的配置存储中——如LaunchDarkly AI Configs(2025年正式版)或等效工具——而非嵌入为会漂移的临时字符串。PR应引用配置键,而非内联粘贴提示词。
  • 运行时终止开关已连接。任何AI功能都应在功能标志后发布,无需重新部署即可禁用。将左移预防与右移遏制结合。
  • 提示词评估测试已存在。至少有一个针对提示词在代表性输入上行为的回归测试(参见
    ai-system-testing
    )。
  • 无虚构API或导入。评审者验证每个导入的符号都真实存在——LLM会编造看似合理的API。

Definition of Done Template

完成定义模板

The Definition of Done (DoD) is the team's shared agreement on what "done" means. It applies to every story before it moves to "Done" on the board.
完成定义(DoD)是团队对“完成”含义的共同约定。它适用于看板上每个标记为“已完成”的需求。

Recommended DoD with Quality Gates

推荐的带质量门禁的DoD

A complete DoD groups its checks under Code Complete, Tested, Quality Gates Pass, Documentation, and Deployment Ready. The Tested group requires unit tests for business logic, integration tests for API/service changes, an E2E test for user-facing critical paths, edge cases and error states covered, and manual exploratory testing completed for medium/high risk changes. The Quality Gates group requires a green CI pipeline, no new lint/type errors, and code coverage not decreased from baseline (a baseline number, not an absolute threshold pulled from the air). See
references/templates.md
for the full copy-paste checklist.
完整的DoD将检查项分为代码完成、已测试、质量门禁通过、文档、部署就绪五个组。已测试组要求业务逻辑有单元测试、API/服务变更有集成测试、用户面向关键路径有E2E测试、覆盖边缘情况和错误状态,以及中高风险变更需完成手动探索性测试。质量门禁组要求CI流水线为绿色、无新的lint/类型错误,以及代码覆盖率不低于基线(基线数值应基于实际情况,而非凭空设定的绝对阈值)。完整的可复制清单请参见
references/templates.md

Enforcing the DoD

强制执行DoD

The DoD is only effective if it is enforced. Three enforcement mechanisms:
  1. Automated gates in CI. Tests must pass, coverage must not decrease, linting must pass. These cannot be bypassed without a team lead override.
  2. PR template checklist. Include the DoD as a checklist in the PR template. Reviewers verify items are checked.
  3. Sprint review validation. During sprint review, stories are accepted only if the DoD is met. "It works but tests are not written yet" means it is not done.

DoD只有在强制执行时才有效。三种强制执行机制:
  1. CI中的自动化门禁。测试必须通过、覆盖率不得降低、lint检查必须通过。这些门禁需要团队负责人批准才能绕过。
  2. PR模板中的清单。在PR模板中包含DoD作为清单。评审者验证条目已勾选。
  3. 迭代评审验证。在迭代评审中,只有满足DoD的需求才会被接受。“功能可用但尚未编写测试”意味着未完成。

Shift-Left Maturity Model

左移成熟度模型

Assess where your team currently sits and identify the concrete next step to improve.
评估团队当前所处阶段,并确定下一步改进的具体行动。

Level 1: Reactive

级别1:被动式

Symptoms:
  • QA tests only after development is complete
  • Bugs found in staging or production
  • No automated tests or minimal coverage
  • Requirements are ambiguous; QA discovers gaps during testing
  • "QA phase" is a distinct block at the end of the sprint
Next step: Introduce QA into sprint planning. Start with QA asking clarifying questions on each story before development begins. Measure: count of requirement gaps found in planning vs. found in testing.
症状:
  • QA仅在开发完成后进行测试
  • bug在预发布或生产环境中被发现
  • 无自动化测试或覆盖率极低
  • 需求模糊;QA在测试期间发现缺口
  • “QA阶段”是迭代末尾的独立环节
下一步: 让QA参与迭代规划。从QA在开发开始前为每个需求提出澄清问题开始。衡量指标:规划阶段发现的需求缺口数量 vs. 测试阶段发现的数量。

Level 2: Gate

级别2:门禁式

Symptoms:
  • QA reviews PRs but does not participate in design
  • Automated tests exist but are written after features are complete
  • Definition of Done exists but testing items are often skipped
  • QA is a checkpoint, not a collaborator
  • Test-after means bugs are found late; rework is common
Next step: Introduce Three Amigos for high-risk stories. QA, dev, and product discuss requirements, edge cases, and test approach before development starts. Measure: reduction in bugs found during QA testing (should decrease as upstream quality improves).
症状:
  • QA评审PR但不参与设计
  • 存在自动化测试但在功能完成后编写
  • 存在完成定义但测试项常被跳过
  • QA是检查点而非协作者
  • 事后测试导致bug发现较晚;返工频繁
下一步: 为高风险需求引入Three Amigos会议。QA、开发和产品在开发开始前讨论需求、边缘情况和测试方法。衡量指标:QA测试期间发现的bug数量减少(随着上游质量提升,该数值应下降)。

Level 3: Embedded

级别3:嵌入式

Symptoms: QA participates in sprint planning and story refinement. Developers write unit and integration tests during development. PR review includes testability checks. QA and dev pair on test case design. DoD enforced with automated quality gates.
Next step: Introduce test-first practices for bug fixes (every bug fix starts with a failing test). Extend to TDD for pure business logic. Measure: regression rate (should approach zero).
症状: QA参与迭代规划和需求细化。开发人员在开发期间编写单元和集成测试。PR评审包含可测试性检查。QA与开发人员结对设计测试用例。DoD通过自动化质量门禁强制执行。
下一步: 为bug修复引入测试先行实践(每个bug修复都从失败测试开始)。将TDD扩展到纯业务逻辑。衡量指标:回归率(应趋近于零)。

Level 4: Collaborative

级别4:协作式

Symptoms: Three Amigos are standard for medium/high risk stories. Developers practice TDD for business logic and bug fixes. QA focuses on exploratory testing, strategy, and risk analysis. Quality metrics tracked and reviewed regularly. Cross-functional ownership of quality.
Next step: Introduce shift-left to architecture and design reviews. QA reviews system design documents for testability before implementation begins. Measure: defect escape rate (consistently below 5%).
症状: Three Amigos会议是中高风险需求的标准流程。开发人员针对业务逻辑和bug修复实践TDD。QA专注于探索性测试、策略和风险分析。定期跟踪和评审质量指标。质量由跨职能团队共同负责。
下一步: 将左移扩展到架构和设计评审。QA在实现前评审系统设计文档的可测试性。衡量指标:缺陷逃逸率(持续低于5%)。

Level 5: Preventive

级别5:预防式

Symptoms: Quality is built into every stage. Defect escape rate consistently below 3%. QA engineers focus on strategy, coaching, and systemic improvement. Production issues are rare and trigger root cause analysis. The team cannot imagine working without early quality practices.
Maintaining this level: Quarterly maturity assessments. New team members onboarded with quality practices from day one. Retrospectives include quality metrics.
症状: 质量内建于每个阶段。缺陷逃逸率持续低于3%。QA工程师专注于策略、指导和系统性改进。生产环境问题罕见,且会触发根本原因分析。团队无法想象没有早期质量实践的工作方式。
维持该级别: 每季度进行成熟度评估。新团队成员从入职第一天起就了解团队的左移实践。回顾会议包含质量指标。

Self-Assessment Worksheet

自我评估工作表

Score eight practices (QA in planning, Three Amigos, PR review, tests-during-dev, failing-test-first bug fixes, TDD for business logic, enforced DoD, metrics review) on a Never/Sometimes/Usually/Always scale to place the team on Levels 1–5. See
references/templates.md
for the printable worksheet with scoring bands.

对八项实践(QA参与规划、Three Amigos会议、PR评审、开发期间编写测试、bug修复先写失败测试、业务逻辑用TDD、强制执行DoD、指标评审)按“从不/有时/通常/总是”评分,以确定团队处于1-5级中的哪个级别。可打印的评分工作表请参见
references/templates.md

Anti-Patterns

反模式

"Shift Left" as QA Layoff

将“左移”作为QA裁员借口

Rebranding "developers write all the tests" as shift-left to justify eliminating QA roles. Shift-left changes WHEN quality happens, not WHO does it. QA engineers bring a testing mindset, risk analysis skills, and exploratory testing capabilities that developers typically do not develop. Removing QA and telling developers to "just test more" results in blind spots, not savings.
将“开发人员编写所有测试”重新包装为左移,以此为理由削减QA岗位。左移改变的是质量验证的时间,而非执行者。QA工程师具备测试思维、风险分析技能和探索性测试能力,这些是开发人员通常不具备的。移除QA并要求开发人员“多测试”会导致盲区,而非成本节约。

Ceremony Without Substance

无实质内容的形式主义

Running Three Amigos meetings as a checkbox exercise where nobody asks hard questions. If the session does not produce at least one changed acceptance criterion or one new edge case, it was not a real discussion. Track "gaps found in Three Amigos" as a metric.
将Three Amigos会议作为走过场的流程,无人提出尖锐问题。如果会议没有产生至少一项修改后的验收标准或一个新的边缘情况,那就不是真正的讨论。跟踪“Three Amigos会议中发现的缺口”作为指标。

All TDD, All the Time

强制全程使用TDD

Forcing TDD on UI prototyping, exploratory spikes, or experimental features where the design is still fluid. TDD works best when the desired behavior is clear. For uncertain domains, spike first, then write tests around the design that emerges. Use the decision guide above.
在UI原型开发、探索性研究或设计仍不稳定的实验性功能中强制使用TDD。TDD在预期行为明确时效果最佳。对于不确定领域,先进行探索,再针对最终形成的设计编写测试。使用上述决策指南。

Quality Gates Without Team Buy-In

无团队共识的质量门禁

Imposing strict quality gates (coverage thresholds, mandatory QA review) without explaining why they exist or involving the team in setting the thresholds. Gates perceived as imposed slow the team and get circumvented. Gates set collaboratively are defended by the team.
在未解释原因或未让团队参与设定阈值的情况下,强加严格的质量门禁(覆盖率阈值、强制QA评审)。被视为强加的门禁会拖慢团队速度并被规避。团队共同设定的门禁会得到团队的维护。

Testing Everything at the Wrong Level

在错误层级测试所有内容

Writing E2E tests for business logic that should be validated by unit tests. Writing unit tests for user flows that need E2E validation. Shift-left is not just "test earlier" -- it is "test at the right level, as early as possible." A calculation bug needs a unit test, not a browser test.
为应通过单元测试验证的业务逻辑编写E2E测试。为需要E2E验证的用户流程编写单元测试。左移不仅是“更早测试”——更是“在正确的层级尽早测试”。计算bug需要单元测试,而非浏览器测试。

Measuring Activity Instead of Outcomes

衡量活动而非结果

Tracking "number of Three Amigos sessions held" instead of "defects found in planning vs. found in production." Activities are inputs; outcomes are outputs. Measure whether shift-left practices actually reduce escaped defects and rework.

跟踪“举办的Three Amigos会议数量”而非“规划阶段发现的缺陷 vs. 生产环境发现的缺陷”。活动是输入,结果是输出。衡量左移实践是否真正减少了逃逸缺陷和返工。

Verification

验证

Prove the gates actually bite — a gate that never fires proves nothing:
  1. A no-test behavioral PR is blocked. Open a throwaway PR that changes behavior with no test (or drops coverage below baseline) and confirm CI goes red and the merge button is disabled. If it merges, the gate is decorative.
  2. The DoD checklist renders in the PR template. Confirm the DoD checklist exists in
    .github/pull_request_template.md
    (or your platform's equivalent) so reviewers see it on every PR —
    test -f .github/pull_request_template.md && grep -qi "unit test" .github/pull_request_template.md
    .
  3. The AI kill switch toggles off. For any AI-powered path, flip its feature flag to disabled in your flag platform and confirm the path goes dark without a redeploy.

证明门禁确实有效——从未触发的门禁毫无意义:
  1. 无测试的行为变更PR被拦截。提交一个无测试的行为变更临时PR(或覆盖率低于基线),确认CI变红且合并按钮被禁用。如果能合并,说明门禁只是装饰性的。
  2. DoD清单显示在PR模板中。确认DoD清单存在于
    .github/pull_request_template.md
    (或你使用平台的等效文件)中,以便评审者在每个PR中都能看到——可执行命令:
    test -f .github/pull_request_template.md && grep -qi "unit test" .github/pull_request_template.md
  3. AI终止开关可关闭。对于任何AI驱动的路径,在标志平台中将其功能标志切换为禁用,确认无需重新部署即可关闭该路径。

Done When

完成标准

  • Definition of Done updated to include test criteria (unit, integration, and E2E gates) and committed to the repo (e.g. present in
    .github/pull_request_template.md
    )
  • PR review checklist with a test-coverage check is checked into the PR template and required by branch protection
  • At least one Three Amigos session run for an upcoming feature, with gaps documented and acceptance criteria updated in the ticket
  • A first dev/QA pairing session has happened, with the agreed test signatures committed to the repo
  • Pre-merge quality gates (test pass, coverage not decreased, linting) are active in CI and a no-test PR is observed to fail (see Verification step 1)
  • A feature flag exists for each risky or AI-powered code path and its disable toggle is verified in the flag platform (see Verification step 3), so prevention (shift-left) and containment (shift-right) ship together
  • 完成定义已更新,包含测试标准(单元、集成和E2E门禁)并提交到代码库(例如存在于
    .github/pull_request_template.md
    中)
  • 包含测试覆盖率检查的PR评审清单已加入PR模板,并被分支保护规则要求执行
  • 至少为一个即将开发的功能举办了一次Three Amigos会议,记录了缺口并更新了工单中的验收标准
  • 已完成首次Dev/QA结对会话,商定的测试签名已提交到代码库
  • 合并前的质量门禁(测试通过、覆盖率不降低、lint检查通过)已在CI中激活,且无测试PR被观察到失败(参见验证步骤1)
  • 每个高风险或AI驱动的代码路径都有功能标志,且其禁用开关已在标志平台中验证(参见验证步骤3),因此左移预防和右移遏制同时交付

Reference Files (in
references/
)

参考文件(位于
references/
目录)

  • tdd-examples.md — Runnable code for dev/QA pairing test-first design, the Red-Green-Refactor password-validator walk-through, and the failing-test-first bug example.
  • templates.md — Copy-paste Definition of Done with quality gates and the shift-left maturity self-assessment worksheet.
  • tdd-examples.md — Dev/QA结对测试先行设计的可运行代码、红-绿-重构密码验证器流程、先写失败测试的bug示例。
  • templates.md — 可复制的带质量门禁的完成定义模板,以及左移成熟度自我评估工作表。

Related Skills

相关技能

  • unit-testing -- Detailed patterns for writing effective unit tests, the primary artifact of shift-left development practices.
  • ai-qa-review -- Automated PR review for test quality and testability, scaling the QA review patterns described here.
  • test-strategy -- The overall testing approach that shift-left practices implement at the daily level.
  • qa-project-context -- Project-specific context that determines which shift-left practices to introduce first.
  • quality-postmortem -- When shift-left fails and defects escape, postmortems identify which practice would have caught them.
  • qa-project-bootstrap -- Onboarding new team members includes introducing them to the team's shift-left practices.
  • unit-testing -- 编写有效单元测试的详细模式,是左移开发实践的核心产物。
  • ai-qa-review -- 针对测试质量和可测试性的自动化PR评审,扩展了本文描述的QA评审模式。
  • test-strategy -- 左移实践在日常层面所实现的整体测试方法。
  • qa-project-context -- 项目特定上下文,决定优先引入哪些左移实践。
  • quality-postmortem -- 当左移失败且缺陷逃逸时,事后复盘会确定本应发现缺陷的实践。
  • qa-project-bootstrap -- 新团队成员入职时,会介绍团队的左移实践。