このページは英語でのみご覧いただけます。
Testing (Vitest + Playwright)
Pathruleルール3件 • メモリ2件 • スキル1件
A layered testing setup that splits fast unit and component tests in Vitest from end-to-end browser tests in Playwright. It pushes assertions toward observable behavior and role-based selectors so tests survive refactors, and it wires both suites into CI with coverage, retries, and trace artifacts.
推奨されるパスの配置
Pathruleは各要素を対応するパスに配置するため、アシスタントはそれが属する場所でだけ参照します。これはインポート時に適用されるスコープで、ワークスペースで調整できます。
ルール
3Select by role and accessible name, not CSS/e2e高助言Playwright locators must follow the role-first hierarchy; CSS and XPath selectors are a last resort.
| 1 | End-to-end tests must locate elements the way a user or screen reader does so they survive markup and styling refactors. |
| 2 | |
| 3 | - Reach for `page.getByRole('button', { name: 'Submit' })` first; it is Playwright's recommended locator and doubles as an accessibility check. |
| 4 | - Fall back in order to `getByLabel`, `getByPlaceholder`, `getByText`, then `getByTestId` only when no semantic handle exists. |
| 5 | - Do not select by CSS class, tag chain, or XPath; these break on every redesign. |
| 6 | - Add `data-testid` to the interactive element itself, not a wrapper, when a test id is genuinely needed. |
Assert observable behavior, not implementation details/src高助言Unit and component tests must verify rendered output and public contracts, never internal state or spy call counts.
| 1 | Tests that assert on implementation details break on every refactor while missing real regressions. |
| 2 | |
| 3 | - Assert on rendered DOM, return values, and emitted events; query with `@testing-library` role and label helpers. |
| 4 | - Do not assert on component internal state, private methods, or mock call counts when an observable effect exists to verify instead. |
| 5 | - Prefer `await screen.findByRole(...)` and `userEvent` interactions over manually reaching into component instances. |
| 6 | - Reserve mocks for true external boundaries (network, timers, randomness); never mock the unit under test. |
Use auto-retrying assertions; ban fixed-time waits/e2e高強制Fixed sleeps and waitForTimeout make tests flaky and slow; Playwright's web-first assertions retry automatically.
| 1 | Flakiness almost always traces back to tests that use fixed delays instead of waiting for a condition to be true. |
| 2 | |
| 3 | - Use `expect(locator).toBeVisible()`, `toHaveText()`, `toBeEnabled()`, and similar web-first assertions; they auto-retry until the timeout with no sleep needed. |
| 4 | - Do not use `page.waitForTimeout(ms)` or `sleep`/`setTimeout` calls in test code; they set an arbitrary floor that is either too short (flaky) or too long (slow). |
| 5 | - Use `page.waitForResponse()` or `waitForURL()` to gate on network or navigation events rather than sleeping after an action. |
| 6 | - Set a `timeout` on the assertion itself when a specific operation is known to be slow rather than adding a blanket sleep before it. |
メモリ
2Two-layer test stack: Vitest units, Playwright e2e/rootVitest owns fast unit and component tests; Playwright owns real-browser end-to-end flows. Keep layers separate.
| 1 | We run two distinct layers so each test sits at the right altitude. Do not drive full app flows from Vitest or unit-test pure logic through Playwright. |
| 2 | |
| 3 | - Unit and component tests live in `/src` next to source or in a `/tests` mirror, run under Vitest with `environment: 'jsdom'` (or `happy-dom`) and `@testing-library/react`. |
| 4 | - End-to-end tests live in `/e2e`, run under `@playwright/test` against a real browser via the `webServer` config entry that boots the app before the suite. |
| 5 | - Vitest Browser Mode (stable since Vitest 3) is appropriate for component tests that need real DOM fidelity without a full browser context; use it instead of jsdom when CSS layout or focus management matters. |
| 6 | - Coverage uses the `v8` provider via `@vitest/coverage-v8`; set `coverage.include` explicitly since `coverage.all` was removed in Vitest 3. |
| 7 | |
| 8 | See /e2e for Playwright selector and wait rules, and /src for the behavior-testing rule. |
Playwright CI config: parallel, retries, traces, sharding/e2eHow the e2e suite is wired for stable and debuggable CI runs.
| 1 | Our `playwright.config.ts` is tuned so CI failures are reproducible and the suite scales. Match these settings when adding projects or CI jobs. |
| 2 | |
| 3 | - `fullyParallel: true`, workers left to Playwright's default locally, `retries: process.env.CI ? 2 : 0`. |
| 4 | - `trace: 'on-first-retry'` ships a full trace (network timeline, DOM snapshots, action log) for the first retry without slowing down green runs. |
| 5 | - `webServer` boots the app with `reuseExistingServer: !process.env.CI` so local runs reuse a running dev server and CI always starts clean. |
| 6 | - For large suites, split across runners with `--shard=1/4` etc. and merge blob reports with `npx playwright merge-reports` for one combined HTML report. |
| 7 | - Before editing a flaky test, open its trace with `npx playwright show-trace trace.zip` to see the exact failure frame; do not guess. |
スキル
1testing-vitest-playwright-review/rootPre-merge checklist for Vitest unit tests and Playwright end-to-end tests.
| 1 | --- |
| 2 | name: testing-vitest-playwright-review |
| 3 | description: Review checklist for any change that adds or edits Vitest unit/component tests or Playwright e2e tests. Confirms tests assert behavior, use stable role-based selectors, avoid fixed-time waits, and run reliably in CI. |
| 4 | --- |
| 5 | |
| 6 | # Testing (Vitest + Playwright) review |
| 7 | |
| 8 | ## Coverage and placement |
| 9 | |
| 10 | - [ ] New logic and components have Vitest tests; new user flows have a Playwright e2e test. |
| 11 | - [ ] Vitest tests live in `/src` or `/tests`; Playwright tests live in `/e2e`. Neither layer is used at the wrong altitude. |
| 12 | |
| 13 | ## Vitest (unit / component) |
| 14 | |
| 15 | - [ ] Assertions target observable output (rendered DOM, return values, events), not internal state or private methods. |
| 16 | - [ ] Component queries use `@testing-library` role and label helpers with `userEvent`; no raw container traversal. |
| 17 | - [ ] Mocks are limited to real boundaries (network, timers, randomness); the unit under test is never mocked. |
| 18 | - [ ] `coverage.include` is set and coverage does not regress; provider is `v8`. |
| 19 | |
| 20 | ## Playwright (e2e) |
| 21 | |
| 22 | - [ ] Locators follow the hierarchy: `getByRole` first, then label/placeholder/text, `getByTestId` last, no raw CSS or XPath. |
| 23 | - [ ] Assertions use web-first matchers (`toBeVisible`, `toHaveText`, `toBeEnabled`); no `waitForTimeout` or fixed-sleep calls. |
| 24 | - [ ] Async navigation/network waits use `waitForURL` or `waitForResponse`, not a sleep after an action. |
| 25 | - [ ] Tests are isolated: one browser context per test, no shared mutable state, no order dependence. |
| 26 | |
| 27 | ## CI configuration |
| 28 | |
| 29 | - [ ] Playwright config has `trace: 'on-first-retry'`, `retries: 2` in CI, `fullyParallel: true`, and a `webServer` entry. |
| 30 | - [ ] CI runs both suites and uploads Playwright trace artifacts on failure. |
| 31 | - [ ] Large suites use `--shard` across runners and merge blob reports. |
このパターンを使う理由
AI-generated tests often assert on implementation details and brittle CSS selectors, so they break on every refactor while missing real user-facing regressions.
対象:Frontend and full-stack teams running Vitest for units and Playwright for end-to-end on a TypeScript codebase.
アシスタントが次のことをしないようにします。
- Brittle e2e tests pinned to CSS classes or DOM structure instead of accessible roles
- Unit tests that assert on internal state, private methods, or call counts instead of observable output
- Flaky CI runs with no traces, no retries, and no parallelism or sharding
- ライセンス
- Apache-2.0
- バージョン
- 1.0.1
- 更新日
- 2026-08-25