test-migration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<objective>
A framework migration is where coverage quietly leaks: twenty old tests become fifteen new ones, a flaky Selenium test is faithfully reproduced as a flaky Playwright test, and the old safety-net suite gets deleted a sprint too early. This skill migrates incrementally with both suites running in CI until parity is proven — so the new suite earns the decommission, you don't just assert it.
</objective>
<objective>
框架迁移往往会导致测试覆盖率悄然流失:20个旧测试变成15个新测试,不稳定的Selenium测试被原封不动地转换成不稳定的Playwright测试,旧的安全网测试套件被过早删除一个迭代周期。本技能采用增量迁移方式,在CI中同时运行新旧两套测试套件,直到证明两者覆盖率一致——新套件需通过验证才能替代旧套件,而非直接断言其合格。
</objective>
Quick Route
快速指引
| You're going from → to | Jump to | First-pass tooling |
|---|---|---|
| Selenium → Playwright | Translation Patterns + | hand-write; no codemod worth trusting |
| Cypress → Playwright | Translation Patterns + | cy2pw web converter / community CLI (see tooling table) |
| Protractor → Playwright | | hand-write; map |
| Jest → Vitest | | |
| Mocha → Vitest | | chai-matcher codemod, then verify |
| Any path, 100+ tests | Migration Workflow + Parallel Running Strategy | always parallel-run in CI |
| 迁移方向 | 跳转至 | 初始工具 |
|---|---|---|
| Selenium → Playwright | 转换模式 + | 手动编写;无可靠的代码转换工具 |
| Cypress → Playwright | 转换模式 + | cy2pw网页转换器 / 社区CLI(见工具表) |
| Protractor → Playwright | | 手动编写;映射 |
| Jest → Vitest | | 使用sed将 |
| Mocha → Vitest | | chai匹配器代码转换工具,然后验证 |
| 任意路径,测试用例≥100个 | 迁移工作流 + 并行运行策略 | 始终在CI中并行运行 |
Discovery Questions
调研问题
Check first. If it exists, use it as context and skip questions already answered there.
.agents/qa-project-context.mdCurrent state:
- What framework are you migrating from and to? (drives the translation tables and which guide section applies)
- How many tests exist, and what is the current flakiness/skip rate? (migrating a flaky test reproduces the flakiness; skipped tests may not be worth migrating)
- Is there a coverage number today? (baseline for the parity track)
Test infrastructure:
- What supporting infrastructure exists? (page objects, custom commands, fixtures, data factories — these migrate before tests)
- How is auth/session handled? (login flows are the most common silent-breakage point — see Failure Modes)
- What CI pipeline runs the tests, and can both frameworks run simultaneously? (parallel-run is non-negotiable)
Constraints:
- Timeline pressure? (urgent = framework EOL like Protractor; comfortable = modernization)
- Budget to run both suites during migration? (double CI cost, temporarily)
- Team's familiarity with the target framework? (training gap drives the workshop/pairing plan)
首先查看。如果该文件存在,将其作为上下文并跳过已回答的问题。
.agents/qa-project-context.md当前状态:
- 你正在从哪个框架迁移到哪个框架?(决定转换表和适用的指南章节)
- 现有多少测试用例,当前的不稳定/跳过率是多少?(迁移不稳定测试会重现不稳定性;被跳过的测试可能不值得迁移)
- 当前是否有测试覆盖率数据?(作为覆盖率一致性跟踪的基准)
测试基础设施:
- 现有哪些支撑性基础设施?(页面对象、自定义命令、夹具、数据工厂——这些需在测试用例之前完成迁移)
- 认证/会话如何处理?(登录流程是最常见的隐性故障点——见故障模式)
- 哪个CI流水线运行测试,能否同时运行两个框架?(并行运行是必须的)
约束条件:
- 时间压力如何?(紧急情况:如Protractor等框架停止维护;宽松情况:技术现代化)
- 迁移期间是否有预算同时运行两套套件?(临时增加一倍CI成本)
- 团队对目标框架的熟悉程度如何?(技能差距决定培训/结对计划)
Core Principles
核心原则
1. Incremental over big bang
1. 优先增量迁移,避免一次性全量迁移
A big-bang rewrite — all tests at once — is the highest-risk approach. It freezes test development for weeks, lands a large batch of unproven tests in one drop, and removes the proven safety net before the replacement exists. Always migrate one test, one module at a time.
一次性重写所有测试是风险最高的方式。它会导致测试开发停滞数周,一次性引入大量未经验证的测试,并且在替代方案成熟前就移除了已验证的安全网。请始终逐个测试、逐个模块地进行迁移。
2. Parallel run until parity
2. 并行运行直至覆盖率一致
Run both suites in CI until the new one provides at least the coverage of the old one. The old suite is your safety net; keep it non-blocking but present. Do not decommission until the new suite has caught real regressions over multiple sprints.
在CI中同时运行两套套件,直到新套件的覆盖率至少与旧套件持平。旧套件是你的安全网;保持其非阻塞状态但持续运行。只有当新套件在多个迭代周期内成功捕获真实回归问题后,才能停用旧套件。
3. Migrate highest-value tests first
3. 优先迁移高价值测试用例
Start with critical user journeys, frequently-failing tests (which benefit most from a better framework), and high-risk areas. Save low-value tests for last — some are not worth migrating at all, and that's a valid, documented decision.
从关键用户旅程、频繁失败的测试(能从更优框架中最大程度获益)和高风险领域开始迁移。低价值测试留到最后——部分测试可能不值得迁移,这是合理且需记录的决策。
4. Modernize patterns during migration, don't just translate
4. 迁移时优化模式,而非单纯转换
Translating a bad Selenium test into a bad Playwright test wastes the opportunity. For each test ask "how would I write this from scratch in the target framework?" — user-facing locators, auto-waiting, fixtures. This applies tenfold to AI-codemod output (see Anti-Patterns).
将糟糕的Selenium测试转换为糟糕的Playwright测试是浪费机会。针对每个测试,思考“如果在目标框架中从零开始编写,我会怎么做?”——比如面向用户的定位器、自动等待、夹具等。这一点对AI代码转换工具的输出尤为重要(见反模式)。
Migration Workflow
迁移工作流
Six phases for a typical multi-sprint migration. Use the checklists inline; heavy code lives in references.
Phase 1 — Audit existing suite (Week 1). Count tests by category, skipped/flaky percentage, coverage if measured, runtime, page-object/utility files, custom plugins, CI stages. Then categorize each test: Critical (revenue flows) → High (core journeys) → Medium (secondary) → Low (admin/edge) → Skip (disabled, duplicate, obsolete). This priority order drives everything downstream.
Phase 2 — Set up target framework (Week 1-2). Install alongside the old one. Create the config ( / ), a separate test directory, a non-blocking CI stage, one smoke test to prove the setup, reporters matching the existing format, shared env/secrets.
playwright.config.tsvitest.config.tsPhase 3 — Migrate shared infrastructure (Week 2-3). Infrastructure before tests, in this order: base page object/test base → auth helpers → API client helpers → common page objects (nav/header/footer) → data factories → custom assertions → feature-specific page objects (with their tests). Capture here so migrated tests skip the login flow.
storageStatePhase 4 — Migrate tests by priority (Week 3-8+). Per test: read the old one and understand what it actually verifies → write the new one from scratch with modern patterns (do not line-by-line translate) → run locally green → run in CI green → tag the old one "migrated" (don't delete) → after one sprint of parallel passing, delete the old one.
Phase 5 — Parallel run in CI (throughout). Both suites run every pipeline. The legacy suite stays non-blocking () until the new suite reaches parity; then flip blocking onto the new suite and remove the old job. See for the full GitHub Actions workflow.
continue-on-error: truereferences/parallel-ci.mdPhase 6 — Decommission old framework (final). Only after parity + stability: all critical/high tests migrated, new suite green in CI for 2+ consecutive sprints, new-suite flakiness ≤ old, coverage comparison shows no regression, team writing new tests in the new framework for 2+ sprints. Then remove old deps from , delete old test files (not just disable), update CI to run only the new suite, update docs.
package.json典型多迭代迁移分为六个阶段。使用内置检查清单;核心代码位于参考文件中。
阶段1 — 审计现有套件(第1周) 按类别统计测试用例数量、不稳定/跳过测试占比(若已统计)、覆盖率、运行时间、页面对象/工具文件、自定义插件、CI阶段。然后对每个测试进行分类:关键(收入相关流程)→ 高优先级(核心用户旅程)→ 中优先级(次要功能)→ 低优先级(后台/边缘场景)→ 跳过(禁用、重复、过时)。此优先级顺序将指导后续所有工作。
阶段2 — 搭建目标框架(第1-2周) 在旧框架旁安装目标框架。创建配置文件( / )、独立测试目录、非阻塞CI阶段、一个验证搭建成功的冒烟测试、与现有格式匹配的报告器、共享环境变量/密钥。
playwright.config.tsvitest.config.ts阶段3 — 迁移共享基础设施(第2-3周) 先迁移基础设施,再迁移测试用例,顺序如下:基础页面对象/测试基类 → 认证助手 → API客户端助手 → 通用页面对象(导航/页眉/页脚)→ 数据工厂 → 自定义断言 → 功能特定页面对象(及其测试用例)。在此阶段捕获,以便迁移后的测试跳过登录流程。
storageState阶段4 — 按优先级迁移测试用例(第3-8周+) 针对每个测试:阅读旧测试并理解其实际验证内容 → 使用现代模式从零编写新测试(不要逐行转换)→ 本地运行通过 → CI运行通过 → 为旧测试标记“已迁移”(不要删除)→ 并行运行通过一个迭代周期后,删除旧测试。
阶段5 — CI并行运行(全程) 每个流水线都运行两套套件。旧套件保持非阻塞状态(),直到新套件达到覆盖率一致;之后将阻塞状态切换到新套件并移除旧任务。完整GitHub Actions工作流见。
continue-on-error: truereferences/parallel-ci.md阶段6 — 停用旧框架(最终阶段) 仅在覆盖率一致且稳定后执行:所有关键/高优先级测试已迁移,新套件在CI中连续2+个迭代周期运行正常,新套件不稳定率≤旧套件,覆盖率对比无退化,团队已连续2+个迭代周期在新框架中编写新测试。然后从中移除旧依赖,删除旧测试文件(而非仅禁用),更新CI使其仅运行新套件,更新文档。
package.jsonAutomated Migration Tooling
自动化迁移工具
There is no AI magic button. Pick the right first-pass tool by path, then refine by hand using .
references/framework-guides.md| Tool | Use when | Don't trust for |
|---|---|---|
| cy2pw web converter (demo.playwright.dev/cy2pw) | Cypress→Playwright, straightforward specs; official, deterministic, browser UI | custom commands, POM conventions, fixture setup |
| Cypress→Playwright bulk first pass over a directory | anything timing-dependent — review every file |
| AI agents (Claude Code, Cursor) | custom-command and fixture translation, the parts converters can't do | a finished test — treat output as a first pass only |
Playwright 1.59+ agentic CLI ( | post-migration triage of a failing migrated test | the migration itself — these are debug tools, not converters |
Avoid:— there is no such built-in Playwright CLI command; the instruction fails at the terminal (verified June 2026). Use cy2pw or the community CLI above.npx playwright migrate
Golden-reference recipe. Before letting any AI or codemod batch the suite, hand-migrate ONE representative test end to end. Commit it as the team's canonical pattern (e.g. ). Feed it back to the AI as a few-shot reference and point human reviewers at it. Every later migration anchors to this file — it's the single highest-leverage tactic for keeping AI output and reviewers consistent.
e2e/_golden/login.spec.ts不存在一键式AI魔法工具。根据迁移路径选择合适的初始工具,然后使用手动优化。
references/framework-guides.md| 工具 | 适用场景 | 不可信任场景 |
|---|---|---|
| cy2pw网页转换器 (demo.playwright.dev/cy2pw) | Cypress→Playwright,简单测试用例;官方工具、确定性强、支持浏览器UI | 自定义命令、页面对象模型约定、夹具设置 |
| Cypress→Playwright批量初始转换整个目录 | 任何与时间相关的内容——需逐文件审核 |
| AI代理(Claude Code、Cursor) | 自定义命令和夹具转换,工具无法处理的部分 | 生成最终测试——仅将输出视为初始版本 |
Playwright 1.59+智能CLI ( | 迁移后调试失败的测试 | 迁移本身——这些是调试工具,而非转换工具 |
注意: 避免使用——Playwright没有内置此CLI命令;该指令会在终端执行失败(2026年6月验证)。请使用上述cy2pw或社区CLI。npx playwright migrate
黄金参考方案 在让任何AI或代码转换工具批量处理套件前,手动端到端迁移一个代表性测试。将其提交为团队的规范模板(如)。将其作为示例反馈给AI,并让人工审核人员参考该文件。后续所有迁移都以此文件为基准——这是确保AI输出和审核人员一致性的最高效策略。
e2e/_golden/login.spec.tsTranslation Patterns
转换模式
Locator mapping
定位器映射
| Old Pattern | New Pattern (Playwright) | Notes |
|---|---|---|
| | Prefer role-based |
| | Use user-visible text |
| | ARIA roles are more stable |
| | testid as fallback |
| | Semantic elements preferred |
| | Specific role is better |
| | Angular model → label |
Role/label names above are illustrative — replace them with the accessible name your app actually renders.
| 旧模式 | 新模式(Playwright) | 说明 |
|---|---|---|
| | 优先使用基于角色的定位器 |
| | 使用用户可见文本 |
| | ARIA角色更稳定 |
| | testid作为备选方案 |
| | 优先使用语义化元素 |
| | 特定角色更优 |
| | Angular模型 → 标签 |
上述角色/标签名称仅为示例——请替换为应用实际渲染的可访问名称。
Wait strategy mapping
等待策略映射
| Old Pattern | New Pattern (Playwright) | Notes |
|---|---|---|
| (remove entirely) | Playwright auto-waits |
| (remove entirely) | Auto-wait on actions |
| (remove entirely) | Auto-wait on assertions |
| | Explicit network wait (start the promise before the action) |
| | Web-first assertion |
| (remove — configure in config) | Use |
| | Web-first assertions retry |
| 旧模式 | 新模式(Playwright) | 说明 |
|---|---|---|
| (完全移除) | Playwright自动等待 |
| (完全移除) | 操作时自动等待 |
| (完全移除) | 断言时自动等待 |
| | 显式网络等待(在操作前启动Promise) |
| | Web优先断言 |
| (移除——在配置中设置) | 在配置中使用 |
| | Web优先断言会自动重试 |
Assertion mapping
断言映射
| Old Pattern | New Pattern (Playwright) | Notes |
|---|---|---|
| | Auto-retrying |
| | Auto-retrying |
| | Auto-retrying |
| | Auto-retrying |
| | Auto-retrying |
| 旧模式 | 新模式(Playwright) | 说明 |
|---|---|---|
| | 自动重试 |
| | 自动重试 |
| | 自动重试 |
| | 自动重试 |
| | 自动重试 |
Config mapping (Cypress → Playwright)
配置映射(Cypress → Playwright)
| Old (Cypress) | New (Playwright) |
|---|---|
| |
| |
| |
| |
| |
| |
| 旧配置(Cypress) | 新配置(Playwright) |
|---|---|
| |
| |
| |
| |
| |
| |
Specific Migration Guides
特定迁移指南
Each path has its own key differences, before/after code, and migration-notes checklist in . Quick orientation:
references/framework-guides.md- Selenium → Playwright: Drop all explicit waits (Playwright auto-waits), swap string locators for /
getByRole/getByLabel, replace WebDriver sessions withgetByTestId. CaptureBrowserContextinstead of re-implementing login.storageState - Jest → Vitest (target Vitest 4.x): Mostly API-compatible — replace with
jest., convertvi.tojest.config.js, drop Babel/ts-jest transforms (but keep an esbuild/SWC equivalent if you use custom Babel plugins like emotion/styled-components macros). Expect 2-10x faster runs. Use Vitest 4.1 testvitest.config.tsfor incremental cutover.tags - Cypress → Playwright (target PW ≥ 1.50): The big shift is command queue → async/await. +
cy.intercept()becomescy.wait()+page.route(); custom commands become fixtures. Mind the 1.52page.waitForResponse()glob and Cookie-header breaking changes (set cookies viapage.route(), not a header override).browserContext.addCookies() - Mocha → Vitest: Near 1:1. /
describe/hooks are unchanged; convert chai matchers (it→to.equal,toBe→to.deep.equal,toEqual→to.contain) andtoContain→sinon/vi.fn().vi.spyOn() - Protractor → Playwright: EOL since 2023 — urgent. Remove , map
waitForAngular/by.modeltoby.binding/getByLabel/getByText, andgetByTestIdbecomesonPrepare.globalSetup
每个迁移路径都有其关键差异、前后代码对比和迁移注意事项清单,详见。快速说明:
references/framework-guides.md- Selenium → Playwright: 移除所有显式等待(Playwright自动等待),将字符串定位器替换为/
getByRole/getByLabel,将WebDriver会话替换为getByTestId。捕获BrowserContext而非重新实现登录流程。storageState - Jest → Vitest(目标Vitest 4.x):API基本兼容——将替换为
jest.,将vi.转换为jest.config.js,移除Babel/ts-jest转换(但如果使用自定义Babel插件如emotion/styled-components宏,需保留esbuild/SWC等效工具)。预计运行速度提升2-10倍。使用Vitest 4.1测试vitest.config.ts进行增量切换。tags - Cypress → Playwright(目标PW ≥ 1.50):最大变化是命令队列→异步/await。+
cy.intercept()变为cy.wait()+page.route();自定义命令变为夹具。注意1.52版本page.waitForResponse()通配符和Cookie头的破坏性变更(通过page.route()设置Cookie,而非覆盖头信息)。browserContext.addCookies() - Mocha → Vitest: 几乎1:1兼容。/
describe/钩子函数不变;转换chai匹配器(it→to.equal,toBe→to.deep.equal,toEqual→to.contain)以及toContain→sinon/vi.fn()。vi.spyOn() - Protractor → Playwright: 2023年已停止维护——紧急迁移。移除,将
waitForAngular/by.model映射到by.binding/getByLabel/getByText,getByTestId变为onPrepare。globalSetup
Parallel Running Strategy
并行运行策略
Coverage comparison during migration
迁移期间覆盖率对比
Track parity between old and new suites in a spreadsheet so nothing leaks. This artifact is the objective check at decommission time.
Feature Area | Old Suite Tests | New Suite Tests | Parity | Notes
Login/Auth | 8 | 8 | 100% | Complete
Dashboard | 12 | 7 | 58% | In progress
Search | 6 | 0 | 0% | Not started
Checkout | 15 | 15 | 100% | Complete
User Settings | 4 | 4 | 100% | Complete
Admin Panel | 20 | 0 | 0% | Low priority
--- | --- | --- | --- |
Total | 65 | 34 | 52% | On track for Q2使用电子表格跟踪新旧套件的覆盖率一致性,避免覆盖率流失。该文件是停用旧套件时的客观验证依据。
功能领域 | 旧套件测试数 | 新套件测试数 | 一致性 | 备注
登录/认证 | 8 | 8 | 100% | 已完成
仪表盘 | 12 | 7 | 58% | 进行中
搜索 | 6 | 0 | 0% | 未开始
结账 | 15 | 15 | 100% | 已完成
用户设置 | 4 | 4 | 100% | 已完成
后台管理面板 | 20 | 0 | 0% | 低优先级
--- | --- | --- | --- |
总计 | 65 | 34 | 52% | 按Q2计划推进Gradual cutover timeline
逐步切换时间线
For a 200-test suite, plan ~10 sprints: setup + infrastructure (Sprint 1-2), critical-path migration (Sprint 3-5, ~50 tests), bulk migration (Sprint 6-8), cleanup + decommission (Sprint 9-10). The old suite starts blocking and becomes non-blocking as parity approaches. New tests are written exclusively in the new framework from Sprint 3 onward.
对于200个测试用例的套件,计划约10个迭代周期:搭建+基础设施(第1-2迭代)、关键路径迁移(第3-5迭代,约50个测试)、批量迁移(第6-8迭代)、清理+停用(第9-10迭代)。旧套件初始为阻塞状态,随着覆盖率接近一致转为非阻塞状态。从第3迭代开始,新测试仅在新框架中编写。
When to delete old tests
何时删除旧测试
Tag old tests "migrated" rather than deleting immediately. Delete only after the new equivalent has passed in CI for 2+ weeks and a manual review confirms no unique assertions are lost. If the old test catches a regression the new one misses, enhance the new test first.
为旧测试标记“已迁移”而非立即删除。仅当对应的新测试在CI中连续通过2+周,且人工审核确认未丢失唯一断言后,再删除旧测试。如果旧测试捕获到新测试未覆盖的回归问题,需先优化新测试。
Anti-Patterns
反模式
Big bang migration
一次性全量迁移
Stopping all development for 3 months to rewrite every test at once. The team cannot ship new tests during the rewrite, coverage freezes, and the new suite is untested in CI until it lands all at once.
Fix: Incremental migration with parallel running. Migrate one module per sprint. Both suites run in CI throughout. New tests are written in the new framework from day one.
停止所有开发3个月以重写所有测试。团队在此期间无法编写新测试,覆盖率停滞,新套件在CI中从未经过验证就一次性上线。
修复方案: 采用增量迁移+并行运行。每个迭代迁移一个模块。全程在CI中运行两套套件。从第一天开始,新测试仅在新框架中编写。
Translating without modernizing
单纯转换而不优化
Line-by-line translation of Selenium tests into Playwright tests, preserving explicit waits, CSS selectors, and fragile patterns. The tests are in a new framework but have all the old problems.
Fix: Rewrite each test using the target framework's best practices — instead of CSS, no explicit waits, fixtures instead of . The migration is an opportunity to improve every test.
getByRolebeforeEach逐行将Selenium测试转换为Playwright测试,保留显式等待、CSS选择器和脆弱模式。测试虽然在新框架中,但仍存在旧问题。
修复方案: 使用目标框架的最佳实践重写每个测试——用替代CSS选择器,移除显式等待,用夹具替代。迁移是优化每个测试的绝佳机会。
getByRolebeforeEachTrusting AI codemods as the final answer
将AI代码转换工具的输出视为最终结果
Cursor, Aider, Continue, Claude Code, and the cy2pw/community converters all do mechanical translation, but quality is uneven and the "translate, don't modernize" trap applies tenfold to their output.
Fix: Run the tool on ONE file, diff against the source. If it modernized correctly, batch the rest. If it just translated, write your own golden-reference file and feed it back as a few-shot. After every pass, parallel-run against the original suite — if results diverge, the tool got it wrong; investigate before promoting.
Cursor、Aider、Continue、Claude Code以及cy2pw/社区转换器均进行机械转换,但质量参差不齐,且“单纯转换而非优化”的陷阱对其输出尤为明显。
修复方案: 在单个文件上运行工具,与源文件对比。如果工具正确优化了模式,再批量处理其余文件。如果仅进行了转换,编写自己的黄金参考文件并作为示例反馈给AI。每次转换后,与原套件并行运行——如果结果不一致,说明工具转换错误;在推广前需调查原因。
No parallel running
不进行并行运行
Decommissioning the old suite before the new suite is proven. A regression slips through because the new suite was missing a test that existed in the old one.
Fix: Run both suites in CI for at least 2 sprints after reaching parity. The old suite is cheap insurance. Only decommission once the new suite has caught regressions on its own.
在新套件验证通过前就停用旧套件。由于新套件缺少旧套件中的某个测试,导致回归问题未被发现。
修复方案: 达到覆盖率一致后,在CI中同时运行两套套件至少2个迭代周期。旧套件是低成本的保障措施。仅当新套件自行捕获到回归问题后,才能停用旧套件。
Losing coverage during migration
迁移期间丢失覆盖率
Twenty old tests become fifteen new ones because "some were redundant" — but nobody verified whether the deleted tests covered unique scenarios.
Fix: Map each old test to its new equivalent explicitly in the coverage spreadsheet. If an old test is intentionally not migrated, document why and verify its coverage is provided elsewhere.
20个旧测试变成15个新测试,理由是“部分测试冗余”——但无人验证被删除的测试是否覆盖了独特场景。
修复方案: 在覆盖率电子表格中明确映射每个旧测试对应的新测试。如果有意不迁移某个旧测试,需记录原因并验证其覆盖率已由其他测试覆盖。
Migrating flaky tests as-is
原样迁移不稳定测试
A test flaky in Selenium will be flaky in Playwright if the root cause is test design (shared state, timing assumptions, non-deterministic data). Faithful migration reproduces the flakiness.
Fix: Diagnose the flakiness first, fix the root cause, then write the new test with the fix baked in. Migration is the best time to fix flakiness because you're rewriting the test anyway. For runtime per-test triage, see .
test-reliability如果测试不稳定的根源是测试设计(共享状态、时间假设、非确定性数据),那么Selenium中的不稳定测试在Playwright中仍会不稳定。原样迁移会重现不稳定性。
修复方案: 先诊断不稳定原因,修复根源问题,然后编写包含修复的新测试。迁移是修复不稳定测试的最佳时机,因为你正在重写测试。如需运行时逐个测试分类,见。
test-reliabilityNo team training
不进行团队培训
Migrating to Playwright while the team has never used it means the champions write everything and the rest of the team can't maintain it.
Fix: Run a 2-hour workshop before starting. Pair-program the first 10 migrated tests (champion + team member). Write a team style guide for the new framework. Require 2+ reviewers per migrated test.
迁移到Playwright但团队从未使用过该框架,导致核心成员编写所有测试,其他团队成员无法维护。
修复方案: 开始前开展2小时培训。结对编程完成前10个迁移测试(核心成员+团队成员)。编写新框架的团队风格指南。要求每个迁移测试至少有2名审核人员。
Failure Modes
故障模式
| Symptom | Likely cause | Fix or check |
|---|---|---|
| Migrated test logs in fresh every run / session lost mid-test | No | Capture |
| No such built-in CLI exists | Use cy2pw web converter or |
| Migrated intercept never matches | 1.52 glob change dropped | Escape the chars or rewrite the route as a regex |
Cookies set on | Cookie header on | Set cookies via |
| New test passes locally, flakes in CI | Old timing assumption translated literally | Replace |
| Test count dropped after a codemod pass | Codemod silently skipped unsupported syntax | Diff test counts per feature area against the parity sheet before promoting |
| 症状 | 可能原因 | 修复或检查点 |
|---|---|---|
| 迁移后的测试每次运行都重新登录 / 会话在测试中途丢失 | 未使用 | 在 |
| 不存在内置此CLI命令 | 使用cy2pw网页转换器或 |
| 迁移后的拦截从未匹配 | 1.52版本通配符变更移除了 | 转义字符或将路由重写为正则表达式 |
在 | | 通过 |
| 新测试本地运行通过,CI中不稳定 | 原样转换了旧的时间假设 | 将 |
| 代码转换后测试数量减少 | 代码转换工具静默跳过了不支持的语法 | 推广前对比每个功能领域的测试数量与一致性表格 |
Verification
验证
Prove the migrated artifacts work — smallest check first:
- The migrated test passes: (or
npx playwright test <migrated-file>) exits 0. A green run is the floor, not the finish.npx vitest run <migrated-file> - No count leaked: diff the new vs old test count per feature area against the coverage spreadsheet. Numbers in the "New Suite Tests" column match what actually ran (per area).
npx playwright test --list | wc -l - Both suites run in CI: the parallel-run workflow shows the legacy job as and the new job blocking; both appear in the pipeline run.
continue-on-error: true - No regression introduced: the new suite stays green across 2+ consecutive sprint CI runs before any old test is deleted.
证明迁移后的工件可用——从最小检查点开始:
- 迁移后的测试通过: (或
npx playwright test <migrated-file>)返回0。运行通过是最低要求,而非最终目标。npx vitest run <migrated-file> - 无数量流失: 对比新套件与旧套件每个功能领域的测试数量,与覆盖率电子表格一致。“新套件测试数”列的数值与实际运行数量匹配(每个领域运行)。
npx playwright test --list | wc -l - 两套套件在CI中运行: 并行运行工作流显示旧任务为,新任务为阻塞状态;两者均出现在流水线运行中。
continue-on-error: true - 未引入回归: 在删除任何旧测试前,新套件在CI中连续2+个迭代周期运行正常。
Done When
完成标准
- Migration scope is defined: which tests move first (critical paths), last (low priority), and which are intentionally not migrated (each with documented rationale in the coverage spreadsheet).
- The coverage-parity spreadsheet shows 100% for every critical/high feature area, with no drop in test count versus the mapped old tests.
- Both frameworks have run in CI in parallel for at least 2 consecutive sprints with the new suite green.
- A migration retrospective document exists capturing flakiness root causes, pattern improvements, and team-training gaps.
- Old framework is fully removed: dependencies deleted from , old test files deleted (not just disabled), and CI config updated to run only the new suite.
package.json
- 迁移范围已定义:哪些测试优先迁移(关键路径)、最后迁移(低优先级)、哪些有意不迁移(每个决策均在覆盖率电子表格中记录理由)。
- 覆盖率一致性表格显示所有关键/高优先级功能领域达到100%,测试数量与映射的旧测试相比无减少。
- 两个框架已在CI中并行运行至少2个连续迭代周期,且新套件运行正常。
- 存在迁移回顾文档,记录不稳定根源、模式改进和团队培训差距。
- 旧框架已完全移除:从中删除依赖,删除旧测试文件(而非仅禁用),更新CI配置使其仅运行新套件。
package.json
Reference Files (in references/
)
references/参考文件(位于references/
)
references/- framework-guides.md — Full before/after code and migration-notes checklists for all five paths: Selenium→Playwright, Jest→Vitest, Cypress→Playwright, Mocha→Vitest, Protractor→Playwright.
- parallel-ci.md — GitHub Actions parallel-suite workflow for running the old and new frameworks side by side during migration.
- framework-guides.md — 所有五个迁移路径的完整前后代码对比和迁移注意事项清单:Selenium→Playwright、Jest→Vitest、Cypress→Playwright、Mocha→Vitest、Protractor→Playwright。
- parallel-ci.md — GitHub Actions并行套件工作流,用于迁移期间同时运行新旧框架。
Related Skills
相关技能
- playwright-automation — target-framework best practices for Selenium/Cypress/Protractor migrations; go there to write idiomatic Playwright once translated.
- cypress-automation — if you're migrating to Cypress, or need source-side Cypress detail.
- unit-testing — Jest→Vitest patterns, mocks, and coverage config in depth.
- test-reliability — heal one flaky test at runtime; use it when migration surfaces flakiness you must triage rather than rewrite.
- selector-drift-recovery — bulk selector regeneration after a UI refactor on the SAME framework; not a framework change.
- ci-cd-integration — parallel-CI configuration for running both suites during migration.
- qa-metrics — track migration progress: test-count parity, flakiness comparison, coverage delta.
- test-strategy — migration decisions should align with the overall multi-quarter test strategy.
- playwright-automation — Selenium/Cypress/Protractor迁移的目标框架最佳实践;转换完成后,可前往此处编写符合规范的Playwright测试。
- cypress-automation — 如果迁移到Cypress,或需要源框架Cypress的详细信息。
- unit-testing — Jest→Vitest模式、模拟和覆盖率配置的深入内容。
- test-reliability — 运行时修复单个不稳定测试;当迁移暴露了需分类而非重写的不稳定测试时使用。
- selector-drift-recovery — 同一框架下UI重构后的批量定位器重生成;不属于框架变更。
- ci-cd-integration — 迁移期间运行两套套件的并行CI配置。
- qa-metrics — 跟踪迁移进度:测试数量一致性、不稳定率对比、覆盖率差异。
- test-strategy — 迁移决策应与整体多季度测试策略保持一致。