Skip to content

필사 모드: フロントエンドテスト 2026 — Playwright / Cypress / Vitest / Jest / Storybook 9 / Chromatic 徹底比較

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

プロローグ — 「Selenium一つで全てを賄った時代は終わった」

2018年頃に「フロントエンドのテストは何を使う?」と聞けば、答えはシンプルだった。ユニットはJest、E2EはSeleniumかCypress、ビジュアルリグレッションは気合のある人だけBackstopJS。それだけだった。「コンポーネント単位のテスト」という言葉はまだぎこちなく、「Storybookがテストインフラ」という発想はなかった。

2026年5月現在、その絵は粉々になった。ある会社のフロントエンドテストパイプラインを描けば、だいたいこんな形だ。

- **ユニットテスト** — Vitest 3またはJest 30、Testing Libraryと一緒に。

- **コンポーネントテスト** — Storybook 9 + Vitest、もしくはPlaywright Component Testing。

- **E2Eテスト** — Playwright 1.50+(半分以上)、Cypress 14、WebdriverIO 9。

- **ビジュアルリグレッション** — Chromatic、Percy、Applitools(SaaS)あるいはLoki、BackstopJS、Reg-Suit(OSS)。

- **ネットワークモッキング** — MSW(Mock Service Worker)2.x。

- **AI補助** — Playwright MCP、Browser MCP、Claude / Cursorエージェントが直接テスト作成。

- **CI統合** — GitHub Actions + Playwright trace + Chromatic publish。

この記事は2026年時点で上記ツールがそれぞれどこに立ち、何が得意で何が苦手か、そして「自分のチームは何を選ぶべきか」を整理する。単なるリストではなく — Playwrightの標準化、Vitestの台頭、Storybook 9の軽量化、AIエージェントがブラウザを直接運転する新しいパラダイムまで — 2024〜2026年の間にこの市場を揺らした4つの流れを一緒に見る。

1章・2026年のフロントエンドテスト地図 — Unit / Component / E2E / Visualの4軸

まずは大局。フロントエンドテストは4つの軸に分かれる。

| 軸 | 何を検証するか | 代表ツール |

| --- | --- | --- |

| Unit | 関数、フック、ユーティリティ — 最速のフィードバック | Vitest 3、Jest 30、Mocha |

| Component | コンポーネント単位のレンダリング・相互作用 | Testing Library、Storybook 9 + Vitest、Playwright CT |

| E2E(End-to-End) | ユーザーフロー、複数ページ | Playwright、Cypress 14、WebdriverIO 9、Selenium 5 |

| Visual Regression | ピクセル単位のUI変化検出 | Chromatic、Percy、Applitools、Loki、BackstopJS、Reg-Suit |

ここに2024〜2026年で新たに加わったカテゴリが二つある。

- **Network mocking** — API呼び出しを傍受する層。MSWが事実上の標準。

- **AI agent testing** — LLMが直接ブラウザを運転。Playwright MCP、Browser MCP。

そして2026年のトレンドは明白だ。**「一つのツールで複数の軸を束ねる」**。PlaywrightはE2E + Component + Visualを一括で提供し、Vitestは(Storybookと共に)Unit + Componentを束ねた。Cypressも同様の統合を試みるが速度で押し負ける。点ツールから始めてプラットフォーム化するか、最初からプラットフォームとして来るかの二択。

テスティングピラミッド(ユニットが多く、E2Eが少ない)は今も有効だが — 2026年にはその形が変形した。Mike Cohnのクラシックなピラミッドはコンポーネント層が抜けて「ダイヤモンド」または「トロフィー」型になった。コンポーネントテストが爆発的に増え、ユニットテストはドメインロジック中心に軽くなり、コンポーネントテストが真ん中を埋める。

2章・Playwright — 事実上の標準(VS Code統合、Trace Viewer)

PlaywrightはMicrosoftが作ったE2Eテストツールで、2020年の1.0リリース以降急速に市場を制した。2026年5月時点で1.50+。State of JS 2024調査では使用意向の最も高いE2Eツールに選ばれた。

コア概念

- **Browser context** — 各テストごとに独立したブラウザコンテキスト。Cookie・ストレージは隔離。

- **Auto-waiting** — `click`、`fill`などのアクションが自動的に要素を待つ。明示的なsleepは不要。

- **Locator** — DOM検索が都度再評価されるlazyオブジェクト。stale element問題なし。

- **Trace Viewer** — 失敗したテストのスナップショット・ネットワーク・コンソールをGUIで再生。

- **Component Testing** — React / Vue / Svelteコンポーネントを隔離環境でマウント。

強み

- **速度** — Cypressより2〜3倍速い場合が多い。Chromium・Firefox・WebKitすべてサポート。

- **VS Code拡張** — GUIでテスト作成・実行・デバッグ。Codegenで自動生成。

- **Trace Viewer** — 失敗解析が30秒で済む。他のツールには真似できない。

- **並列実行** — デフォルトでワーカー分散。CIで60%の時間削減はよくある。

- **複数ページ・ドメイン** — 一つのテストで複数オリジンを自由に行き来できる。

弱み

- **学習コスト** — Cypressより抽象化が深い。最初の数日は戸惑う。

- **コンポーネントテストはベータからGAへ** — 1.40系でGAになったが、Vitest + Testing Libraryほど軽量ではない。

- **画像比較はSaaSが強い** — `toHaveScreenshot`はあるが、Chromatic・Percyのベースライン管理には及ばない。

いつ選ぶか

- 新規プロジェクト開始 — ほぼ無条件でPlaywright。

- 複数ブラウザ検証が必要(特にSafari / WebKit)。

- 大きなmonorepoで並列E2Eが必要。

- Traceベースのデバッグが重要なチーム。

// playwright.config.ts

export default defineConfig({

testDir: './e2e',

fullyParallel: true,

retries: process.env.CI ? 2 : 0,

reporter: [['html'], ['github']],

use: {

baseURL: 'http://localhost:3000',

trace: 'on-first-retry',

screenshot: 'only-on-failure',

},

projects: [

{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },

{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },

{ name: 'webkit', use: { ...devices['Desktop Safari'] } },

{ name: 'mobile-chrome', use: { ...devices['Pixel 7'] } },

],

})

// e2e/checkout.spec.ts

test('user can complete checkout', async ({ page }) => {

await page.goto('/products/coffee-beans')

await page.getByRole('button', { name: 'Add to cart' }).click()

await page.getByRole('link', { name: 'Cart' }).click()

await expect(page.getByText('Coffee Beans')).toBeVisible()

await page.getByRole('button', { name: 'Checkout' }).click()

await page.getByLabel('Email').fill('test@example.com')

await page.getByRole('button', { name: 'Place order' }).click()

await expect(page).toHaveURL(/thank-you/)

})

Playwrightの本当の価値はTrace Viewerだ。CIで失敗したテストのtrace.zipを取得してローカルで開けば、各アクションのDOMスナップショット・ネットワーク呼び出し・コンソールログがGUIタイムラインで再生される。「なぜ失敗した?」がキャプチャで終わる。Cypressのビデオ録画の一段上だ。

3章・Cypress 14 — 依然強力

Cypressは2017年頃に登場し、しばらくの間E2Eの標準だった。2026年5月時点で14。シェアはPlaywrightに押されたが、依然大きなユーザーベースを持つ。

コア概念

- **In-browser test runner** — テストが実ブラウザ内で実行される。DOMに直接アクセス。

- **Time-travel debugger** — 各コマンドのスナップショットを左パネルで時系列に追える。

- **Real-time reload** — コードを保存すれば即座にテストが再実行。

- **Cypress Cloud** — クラウドダッシュボード、並列実行分散、flaky検出。

- **Component Testing** — React / Vue / Angularコンポーネントを隔離環境で。

強み

- **DXが圧倒的** — 始めるのが楽。`cy.visit` `cy.get` `cy.click`が直感的。

- **Time-travel debugging** — 各コマンドのDOMスナップショットが自動キャプチャ。デバッグが楽しい。

- **リアルタイムhot reload** — TDDサイクルが速い。

- **豊富なドキュメント・コミュニティ** — Stack Overflowに答えがほぼ全部ある。

弱み

- **単一ドメイン制約** — `cy.origin`が追加されたが、依然複数ドメインは扱いにくい。

- **Safari / WebKitサポートが弱い** — 実験段階、安定性不足。

- **速度** — Playwrightより30〜50%遅い。

- **iframeの扱いが厄介** — 広告や外部ウィジェットを含むページが痛い。

- **Cypress Cloud価格** — 並列実行と結果保存が無料tierですぐ制限。

いつ選ぶか

- 既存のCypressコードベースが大きい場合 — 移行コストが大きい。

- 単一ドメインSPA、小規模チーム。

- デバッグ体験を最優先する場合。

// cypress/e2e/login.cy.js

describe('Login flow', () => {

beforeEach(() => {

cy.intercept('POST', '/api/login', { fixture: 'login-success.json' }).as('login')

cy.visit('/login')

})

it('logs in with valid credentials', () => {

cy.get('[data-cy=email]').type('user@example.com')

cy.get('[data-cy=password]').type('s3cret!')

cy.get('[data-cy=submit]').click()

cy.wait('@login')

cy.url().should('include', '/dashboard')

cy.contains('Welcome back').should('be.visible')

})

})

Cypress 14で追加された最大の機能は**WebKit GA**と**Component Testing UX改善**だ。だがPlaywrightが既に一歩先を行っており、新規プロジェクトがCypressを選ぶ割合は2024年から急速に下がっている。

4章・Vitest 3 — Viteと共に来る最速

Vitestは2021年Anthony Fuが作ったユニットテストランナーで、Viteのトランスフォーマー・HMRをそのまま活用する。2026年時点で3.x、JS / TS新規プロジェクトのユニットテスト標準となった。

コア概念

- **Vite-native** — Vite configをそのまま再利用。esbuild + Rollupがトランスパイル。

- **HMR for tests** — 変更されたモジュールのみ再評価、ミリ秒単位のサイクル。

- **Jest互換API** — `describe` / `it` / `expect`がJestとほぼ同じ。

- **Workspaces** — monorepoで複数パッケージを一つのvitestコマンドで。

- **Browser mode** — 実ブラウザでコンポーネントテスト(Playwright / WebdriverIOバックエンド)。

強み

- **速度が圧倒的** — Jest比2〜10倍速い。コールドスタートも速い。

- **Viteエコシステムと一体** — Viteプロジェクトなら別途設定なしで即動作。

- **TypeScript first-class** — esbuildがトランスパイルするのでts-jestのような迂回が不要。

- **Worker pool最適化** — Node worker_threadsで隔離 + 高速実行。

- **Storybook 9と統合** — `@storybook/addon-vitest`でストーリーがそのままテスト。

弱み

- **CRA / Next.jsレガシー** — Webpackベースのプロジェクトは移行コスト。

- **JSDOM / happy-dom互換性** — 一部のDOM APIで小さな差。

- **Jestの巨大なプラグインエコシステム** — `jest-extended`など一部ミラーリングが不十分。

いつ選ぶか

- Viteを使う全てのプロジェクト。

- 新規プロジェクト開始 — ほぼ無条件でVitest。

- ユニットテスト速度が重要な場合(CI分単位の削減)。

// vitest.config.ts

export default defineConfig({

plugins: [react()],

test: {

globals: true,

environment: 'happy-dom',

setupFiles: ['./test/setup.ts'],

coverage: {

provider: 'v8',

reporter: ['text', 'json', 'html'],

exclude: ['node_modules/', 'test/'],

},

},

})

// src/utils/format.test.ts

describe('formatCurrency', () => {

it('formats JPY without decimals', () => {

expect(formatCurrency(12345, 'JPY')).toBe('¥12,345')

})

it('formats USD with two decimals', () => {

expect(formatCurrency(12.5, 'USD')).toBe('$12.50')

})

it('handles negative numbers', () => {

expect(formatCurrency(-100, 'USD')).toBe('-$100.00')

})

})

Vitest 3の最大の変化は**Browser mode GA**だ。JSDOMではなく実Chromiumでコンポーネントをマウントしてテストする。Playwright Component Testingと似た領域だが、Viteベースのプロジェクトではより自然。

5章・Jest 30 — レガシー + Next互換

JestはFacebookが2014年に作ったユニットテストランナーで、しばらくの間JSテストの事実上の標準だった。2025年9月に30がリリースされ、2026年5月には30.xマイナーリリースが安定段階にある。

コア概念

- **Snapshot testing** — `expect(tree).toMatchSnapshot()` — UIツリーをシリアライズして保存。

- **Module mocking** — `jest.mock()`でimportパスを偽物に置換。

- **Fake timers** — `jest.useFakeTimers()`でsetTimeout / setIntervalを制御。

- **Coverage** — Istanbulベースのカバレッジが内蔵。

強み

- **巨大なエコシステム** — `jest-extended`、`jest-fetch-mock`など数万のプラグイン。

- **CRA / Next.jsデフォルト統合** — Next.jsの`next/jest`が標準設定を提供。

- **安定性** — 10年の検証。大コードベースで信頼性が高い。

- **VS Code統合** — Jest Runner拡張がうまく動く。

弱み

- **速度** — Vitest比2〜5倍遅い。大コードベースでCI時間が負担。

- **ESMサポートがぎこちない** — 一部のESMパッケージでhackが必要。

- **TypeScriptはts-jestまたはbabel** — Vitestのesbuild比で遅い。

いつ選ぶか

- 既存のJestコードベースが大きい場合。

- Next.js 12未満またはWebpackベースのCRA。

- Jest専用プラグインに依存する場合。

// jest.config.js

const nextJest = require('next/jest')

const createJestConfig = nextJest({ dir: './' })

const customConfig = {

setupFilesAfterEach: ['<rootDir>/jest.setup.js'],

testEnvironment: 'jsdom',

moduleNameMapper: {

'^@/(.*)$': '<rootDir>/src/$1',

},

collectCoverageFrom: [

'src/**/*.{ts,tsx}',

'!src/**/*.stories.tsx',

],

}

module.exports = createJestConfig(customConfig)

Jest 30の最大の変化は**初のnative ESMサポート安定化**と**メモリ使用量30%削減**。移行コストのため依然大組織ではJestを使うが、新規プロジェクトでJestを選ぶことは少なくなっている。

6章・Testing Libraryの哲学 — Implementation detailを避ける

Testing Libraryは2018年にKent C. Doddsが作ったライブラリ群だ。DOM、React、Vue、Svelte、Solidそれぞれのアダプターがある。2026年時点で全てのコンポーネントテストの基礎。

中核哲学

- **「The more your tests resemble the way your software is used, the more confidence they can give you.」**

- コンポーネントの内部stateを見ず、ユーザーが見てクリックするものを見る。

- `getByRole`、`getByLabelText`、`getByText` — アクセシビリティ基準のクエリ。

- `getByTestId`は最終手段。

強み

- **リファクタリングに優しい** — コンポーネント内部構造が変わってもテストはそのまま。

- **アクセシビリティと共に進む** — クエリがARIA roleベースなので自然にa11yを検証。

- **フレームワーク独立** — React / Vue / Svelteどこでも同じ哲学。

- **TanStack / Mantine / Radixのようなライブラリも Testing Library基準で構築**。

弱み

- **純粋ユニットテストより遅い** — DOMレンダリングが必要。

- **userEvent対fireEvent** — 二つのAPIの差が初心者に混乱を与える。

- **非同期処理** — `findBy*`、`waitFor`の使い方を混同する人が多い。

例 — React Testing Library + Vitest

describe('LoginForm', () => {

it('shows error when password is too short', async () => {

const user = userEvent.setup()

render(<LoginForm onSubmit={() => {}} />)

await user.type(screen.getByLabelText(/email/i), 'user@example.com')

await user.type(screen.getByLabelText(/password/i), 'abc')

await user.click(screen.getByRole('button', { name: /sign in/i }))

expect(

await screen.findByText(/password must be at least 8 characters/i)

).toBeInTheDocument()

})

it('calls onSubmit with valid input', async () => {

const onSubmit = vi.fn()

const user = userEvent.setup()

render(<LoginForm onSubmit={onSubmit} />)

await user.type(screen.getByLabelText(/email/i), 'user@example.com')

await user.type(screen.getByLabelText(/password/i), 'longerpassword')

await user.click(screen.getByRole('button', { name: /sign in/i }))

expect(onSubmit).toHaveBeenCalledWith({

email: 'user@example.com',

password: 'longerpassword',

})

})

})

よく陥る罠 — `screen.getByText("Loading...")`のようなテキスト完全一致はi18nで壊れる。`getByRole("status")`または正規表現が安全。そして`data-testid="submit-button"`は本当に最終手段としてのみ。ユーザーはtestidを見ない。

7章・Storybook 9(2025年6月) — 軽量化しVitestと統合

Storybookは2016年に登場したコンポーネントワークショップだ。2025年6月にリリースされた9バージョンは大きな転換点だった。軽くなり(バンドルサイズ約50%減)、Vitestと深く統合された。

主要変化(Storybook 9)

- **軽量化** — 9.0発表で「最大75%少ない依存、48%軽いインストール」という数値。

- **Vitestベースのテスト** — `@storybook/addon-vitest`でストーリーがそのままテストに。

- **Component testing** — Play functionが事実上の相互作用テスト標準。

- **Visual testing内蔵** — Chromatic連携がよりスムーズに。

- **A11y検証内蔵** — `@storybook/addon-a11y`がデフォルトオプション化。

強み

- **単一作成、多用途活用** — 一つのストーリーがカタログ・相互作用テスト・ビジュアルリグレッション・a11y検証すべてをカバー。

- **デザイナーとの協業** — Figma統合。デザイントークンをリアルタイム確認。

- **Vitest統合** — ストーリー実行がそのままユニットテスト実行と同じインフラ。

- **Plugins / Addonsエコシステム** — `addon-controls`、`addon-actions`、`addon-docs`。

弱み

- **ビルド時間** — 大きなデザインシステムでStorybookビルドが分単位。

- **CSF(Component Story Format)3** — 学習が必要。最初に書くチームは戸惑う。

- **バンドラー分岐** — ViteベースかWebpackベースかで設定が分かれる。

例 — CSF 3 + Play function

// Button.stories.tsx

const meta: Meta<typeof Button> = {

title: 'UI/Button',

component: Button,

tags: ['autodocs'],

}

export default meta

type Story = StoryObj<typeof Button>

export const Primary: Story = {

args: {

variant: 'primary',

children: 'Click me',

},

}

export const Clicked: Story = {

args: { variant: 'primary', children: 'Click me' },

play: async ({ canvasElement }) => {

const canvas = within(canvasElement)

const btn = canvas.getByRole('button', { name: /click me/i })

await userEvent.click(btn)

await expect(btn).toHaveAttribute('aria-pressed', 'true')

},

}

// vitest.workspace.ts — Storybook 9 + Vitest統合

export default defineWorkspace([

'./vitest.config.ts',

{

extends: './vitest.config.ts',

plugins: [storybookTest({ configDir: '.storybook' })],

test: {

name: 'storybook',

browser: {

enabled: true,

headless: true,

name: 'chromium',

provider: 'playwright',

},

},

},

])

Storybook 9の真の価値は「ストーリーを一度書けばカタログ・テスト・ビジュアルリグレッション・アクセシビリティが全部ついてくる」点だ。デザインシステムチームなら事実上必須。

8章・Chromatic / Percy / Applitools — ビジュアルリグレッション

ビジュアルリグレッション(Visual Regression)はUI変更が意図したものか否かをピクセル単位で検査する。SaaSの三強はChromatic、Percy(BrowserStack)、Applitoolsだ。

Chromatic

- Storybookを作った会社が直接運営。Storybookと一体。

- ストーリー単位のビジュアルリグレッションが強み。

- Cross-browserのベースラインをクラウドに保存。

- レビューワークフロー(diff → approve → merge)が綺麗。

- 価格はsnapshot基準 — 小規模チームは無料tierで十分。

Percy(BrowserStack)

- 2017年BrowserStackが買収。Percy CLIでPlaywright / Cypress / WebdriverIO統合。

- 複数viewport、複数ブラウザのベースライン。

- BrowserStackの実デバイスクラウドと連携。

Applitools

- AIベースのビジュアル比較が強み — 「意味のある変化のみ」を検出。

- Visual AIアルゴリズムがdynamic content(タイムスタンプ、広告)を自動無視。

- Ultrafast Grid — 一度キャプチャして複数ブラウザ・デバイス組合せで検証。

- エンタープライズ価格。大組織で圧倒的。

三者の違い

| 項目 | Chromatic | Percy | Applitools |

| --- | --- | --- | --- |

| 母体 | Storybook | BrowserStack | 独立SaaS |

| 強み | Storybook統合 | 複数viewport、BSデバイス | AI Visual diff |

| 価格モデル | snapshot基準 | snapshot + DOM基準 | enterprise seat |

| Free tier | 寛大(月5,000 snapshot) | 小さい | 評価版のみ |

| AI処理 | 部分的 | 部分的 | 中核機能 |

// Playwright + Percy

test('homepage looks correct', async ({ page }) => {

await page.goto('/')

await percySnapshot(page, 'Homepage')

})

// Playwright + Applitools Eyes

test('checkout flow visual', async ({ page }) => {

const eyes = new Eyes()

const cfg = new Configuration()

cfg.setBatch(new BatchInfo('Smoke 2026-05-16'))

eyes.setConfiguration(cfg)

await eyes.open(page, 'Shop', 'Checkout')

await page.goto('/checkout')

await eyes.check('Checkout page', undefined)

await eyes.close()

})

ビジュアルリグレッションの最大の罠は**flaky snapshot**だ。フォントロード、アニメーション、カルーセル、広告 — このような動的要素をマスキングしなければ95%のdiffがfalse positive。Applitoolsが強い理由はこれを自動で処理するから。

9章・Loki / BackstopJS / Reg-Suit — オープンソースのビジュアルリグレッション

SaaSが負担になる、あるいはベースラインを自分のリポジトリに置きたいならOSSの選択肢がある。

Loki

- Storybook専用。`loki test`で全ストーリーをキャプチャ・比較。

- Chromium / Firefox / WebKitサポート。Dockerベースで一貫したレンダリング。

- ベースラインはgitに一緒にコミット — レビューはPRで。

BackstopJS

- 最も古い(2014年)オープンソースのビジュアルリグレッションツール。

- Puppeteerベース。URLリストとセレクターで定義。

- HTMLレポートが綺麗。小規模チームで依然人気。

Reg-Suit

- 日本発のOSS。メルカリなどが採用。

- S3またはGCSにスナップショット保存。PR diffをGitHubコメントで。

- Playwright / Cypress / Storybookどこからでもキャプチャを投げられる。

三者の違い

| 項目 | Loki | BackstopJS | Reg-Suit |

| --- | --- | --- | --- |

| 母体 | Storybookエコシステム | 独立 | 日本OSS |

| ベースライン保存 | git | ローカル | S3 / GCS |

| キャプチャエンジン | Chromium | Puppeteer | 外部(Playwrightなど) |

| PR統合 | 直接 | 弱い | 強い(GitHub bot) |

// backstop.json — BackstopJSの基本設定

{

"id": "my-project",

"viewports": [

{ "label": "mobile", "width": 375, "height": 667 },

{ "label": "desktop", "width": 1920, "height": 1080 }

],

"scenarios": [

{

"label": "Homepage",

"url": "http://localhost:3000/",

"delay": 500,

"misMatchThreshold": 0.1

}

],

"engine": "puppeteer",

"report": ["browser"]

}

OSSの強みはベースラインを自インフラに置くこと。セキュリティが厳格な金融・ヘルスケアではSaaSを使えない場合が多く、Reg-Suitまたはセルフホストが好まれる。

10章・Browser MCP + Playwright MCP — AIエージェントがブラウザを運転

2024年後半から大きな変化があった。MCP(Model Context Protocol)が標準化され、AIエージェントが直接ブラウザを運転するパターンが一般化した。2026年5月時点でPlaywright MCPとBrowser MCPの二陣営がある。

Playwright MCP(Microsoft)

- Microsoftが直接作った公式MCPサーバー。PlaywrightのすべてのAPIをMCPツールとして公開。

- Claude・Cursor・VS Code Copilotがこれを通してブラウザアクションを呼び出す。

- Accessibility treeベース — スクリーンショットではなく意味的構造でページを見る。

- Traceキャプチャと共に作動。エージェントが作ったテストもTrace Viewerで再生。

Browser MCP

- オープンソース陣営のMCPサーバー。多様なバックエンド(Playwright、Puppeteer、Selenium)。

- Local Chrome拡張を通して現在のユーザーのセッションで作動。

- ログイン状態で作業すべきシナリオに強い。

使用パターン

// .cursor/mcp.json — Playwright MCPを登録

{

"mcpServers": {

"playwright": {

"command": "npx",

"args": ["@playwright/mcp@latest"]

}

}

}

この設定後にAIエージェントに「チェックアウトフローのテストを書いて実行して」と頼めば、エージェントが直接ブラウザを開いてクリック・入力しながら`*.spec.ts`を生成する。Codegenの次世代。

限界

- **flaky** — エージェントが非決定的でテスト自体が安定しない可能性。

- **コスト** — LLMトークンコストが実行ごとに。

- **セキュリティ** — 本番資格情報をエージェントに渡すのは危険。

そこで2026年のパターンは**「エージェントが草案を作成 → 人がレビュー + 安定化 → CIに登録」**だ。エージェントが毎CIで回るのはまだ先。

11章・MSW(Mock Service Worker) + ネットワークモッキング戦略

MSWは2019年Artem Zakharchenkoが作ったネットワークモッキングライブラリだ。2026年時点で2.x、フロントエンドテストの事実上の標準ネットワークモッキングツールとなった。

コア概念

- **Service Workerベース** — ブラウザのネットワーク層で傍受。`fetch`、`axios`、`XHR`問わず。

- **Node環境でも作動** — `setupServer`でVitest / Jestで使用。

- **REST + GraphQL** — 両プロトコル対応。

- **タイプセーフ** — TypeScriptとよく馴染む。

強み

- **アプリコード無修正** — `axios`を`jest.mock()`するのではなく、実ネットワーク呼び出しを傍受。

- **開発・テスト・Storybook共通** — 同じハンドラを三環境で再利用。

- **GraphQLサポート** — Apollo Client / urql統合がスムーズ。

- **Devtools統合** — ブラウザdevtoolsのNetworkタブにそのまま見える。

例 — MSWハンドラ

// mocks/handlers.ts

export const handlers = [

http.get('/api/products', () => {

return HttpResponse.json([

{ id: 1, name: 'Coffee Beans', price: 25000 },

{ id: 2, name: 'Tea Set', price: 35000 },

])

}),

http.post('/api/cart', async ({ request }) => {

const body = await request.json()

return HttpResponse.json({ ok: true, cartId: 'abc-123' }, { status: 201 })

}),

http.get('/api/user/me', () => {

return new HttpResponse(null, { status: 401 })

}),

]

// test/setup.ts — Vitestで

const server = setupServer(...handlers)

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

afterEach(() => server.resetHandlers())

afterAll(() => server.close())

// browser entrypoint(開発環境)

if (process.env.NODE_ENV === 'development') {

const worker = setupWorker(...handlers)

worker.start()

}

MSWの真の価値は**「テスト・開発・Storybookで同じモッキングコードを使う」**点だ。バックエンドがまだないときもフロントエンドが進行可能、テストと実開発が同じfixtureを共有。

代替としてPlaywrightの`page.route()`、Cypressの`cy.intercept()`もあるが — 各ツール専用で再利用性が低い。そこでMSWを下層に置き、E2Eではその上にPlaywright routeを乗せるハイブリッドがよくある。

12章・Page Object / Component Testingパターン

E2Eテストが増えるとコード重複が問題となる。そこで2026年の標準パターンは二つ。

Page Object Model(POM)

- 1ページ = 1クラス。セレクターとアクションをクラスにカプセル化。

- Selenium時代から受け継がれたパターン。2026年もPlaywright・Cypressで有効。

// e2e/pages/CheckoutPage.ts

export class CheckoutPage {

readonly page: Page

readonly emailInput: Locator

readonly submitButton: Locator

constructor(page: Page) {

this.page = page

this.emailInput = page.getByLabel('Email')

this.submitButton = page.getByRole('button', { name: 'Place order' })

}

async goto() {

await this.page.goto('/checkout')

}

async fillEmail(email: string) {

await this.emailInput.fill(email)

}

async submit() {

await this.submitButton.click()

}

async expectSuccess() {

await expect(this.page).toHaveURL(/thank-you/)

}

}

// e2e/checkout.spec.ts

test('user completes checkout', async ({ page }) => {

const checkout = new CheckoutPage(page)

await checkout.goto()

await checkout.fillEmail('user@example.com')

await checkout.submit()

await checkout.expectSuccess()

})

Component Testing

- コンポーネントを隔離環境でマウントして検証。

- Playwright CT、Cypress CT、Vitest browser mode、Storybook play function。

- 「ユニットテスト並みに速くE2E並みに本物っぽい」位置。

どのパターンをいつ

- **ユニット / 純関数** — Vitest、JSDOM。

- **コンポーネント単独** — Storybook + VitestまたはPlaywright CT。

- **2〜3コンポーネント組合せ** — Testing Library + Vitest。

- **ページ全体** — Page Object + Playwright / Cypress。

- **ユーザージャーニー** — Page Object + Playwright、データ隔離。

POMの罠 — 抽象化しすぎるとテストが何をしているか見えない。「Login → Cart → Checkout」が一行で終われば読みやすいが失敗解析が難しい。適度な抽象化 + Playwright Trace Viewerの組合せが最適。

13章・韓国 / 日本の事例 — トス、カカオ、メルカリ

韓国 — トスのUIテスト

トスは100名以上のフロントエンドチームを持つ大組織で、自前のデザインシステム(Toss DS)を運営する。公開ブログ・発表資料に表れるパターンは以下の通り。

- **Storybook + Chromatic** — デザインシステムの全コンポーネントがStorybookに登録。

- **Playwright** — E2Eの標準。マルチブラウザ検証。

- **Vitest + React Testing Library** — コンポーネント単位テスト。

- **自前MSWハンドラライブラリ** — トスAPIパターンに合わせた共通fixture。

- **CIでビジュアルリグレッションが遮断** — Chromatic承認なしではマージ不可。

トスブログの「フロントエンドにテストは本当に必要か?」のような記事に見える哲学は — 「テストはデザインシステムと一体」。コンポーネント単位が強ければページ単位は少なく。

韓国 — カカオのフロントエンド

カカオ陣営(カカオ、カカオバンク、カカオエンタープライズ)も類似スタックだ。

- **JestまたはVitest** — レガシーはJest、新規はVitest。

- **Cypressが多く残っている** — 2020〜2023年に採用したコードベースが多い。

- **Playwrightに移行中** — 新規プロジェクトと大規模移行。

- **カカオバンクはより厳格** — 金融規制で自前インフラ検証、OSSビジュアルリグレッション(Reg-Suitまたは自前)。

日本 — メルカリのコンポーネントテスティング

メルカリはStorybook + Vitest + Reg-Suitの組合せを公開的に発表したことがある。パターンは以下の通り。

- **Storybook** — デザインシステムと全コンポーネント。

- **Reg-Suit** — ビジュアルリグレッション、S3にベースライン、GitHub PRに自動コメント。

- **VitestまたはJest** — ユニット。

- **Playwright** — E2E。

- **MSW** — ネットワークモッキング。

メルカリ Engineering Blogのビジュアルリグレッション記事がReg-Suitの実使用事例としてよく引用される。日本でReg-Suitが強い理由の一つがメルカリの採用。

結論 — 地域別推奨

| シナリオ | 韓国推奨 | 日本推奨 |

| --- | --- | --- |

| スタートアップ(10〜50人) | Vitest + Playwright + Chromatic | Vitest + Playwright + Reg-Suit |

| 中堅(50〜500人) | Storybook 9 + Chromatic + Playwright | Storybook 9 + Reg-Suit + Playwright |

| 大企業(500+) | 自前デザインシステム + Chromatic + Playwright | 自前 + Reg-Suit + Playwright |

| 金融 | 自前ホストReg-Suit + Playwright | 自前ホスト + Selenium 5残存 |

| グローバルSaaS | Applitools + Playwright | Applitools + Playwright |

14章・どのスタックを選ぶべきか — シナリオ別ガイド

シナリオA — 大規模SaaS(数十ページ、多言語、複数ブラウザ)

- **Unit**: Vitest 3 + React Testing Library

- **Component**: Storybook 9 + Vitest browser mode

- **E2E**: Playwright 1.50+(Chromium、Firefox、WebKit、Mobile Safari)

- **Visual**: ChromaticまたはApplitools

- **Network**: MSW 2.x

- **CI**: GitHub Actions + Playwright trace + Chromatic publish + 失敗時Slack

- **AI**: Playwright MCPで新規テスト草案生成

シナリオB — デザインシステム / コンポーネントライブラリ

- **Unit**: Vitest 3

- **Component**: Storybook 9(CSF 3 + play function)

- **Visual**: Chromatic(Storybookと一体)

- **A11y**: `@storybook/addon-a11y` + axe-core

- **Docs**: Storybook autodocs

- **E2Eは最小化** — ライブラリはコンポーネント単位が核心

シナリオC — E-commerce(カート、決済、複数ページ)

- **Unit**: Vitest 3

- **Component**: Storybook 9またはTesting Library

- **E2E**: Playwright(Page Objectパターン)

- **Visual**: PercyまたはChromatic(モバイルviewport核心)

- **Network**: MSW + Playwright routeハイブリッド

- **決済フローは隔離されたテストアカウント + Stripe test mode**

シナリオD — メディア / コンテンツサイト

- **Unit**: Vitest 3(SEOメタ検証中心)

- **E2E**: Playwright(Lighthouse CIと共に)

- **Visual**: ChromaticまたはBackstopJS

- **Network**: MSWでCMS応答モッキング

- **パフォーマンス回帰が重要** — Playwright + Lighthouse統合

シナリオE — レガシー移行(Jest + Cypress → Vitest + Playwright)

- 一度に全部移行せず、新コードは新ツールで。

- JestとVitest共存 — `vitest run --project new`で漸進的に。

- Cypress E2Eはそのまま残し、新規E2EだけPlaywright。

- 12〜18ヶ月の移行が現実的。

コスト見積もり(2026年5月基準、50人フロントエンドチーム)

| ツール | 無料tier | 有料(月額) |

| --- | --- | --- |

| Playwright | 無料 | — |

| Vitest | 無料 | — |

| Storybook | 無料 | — |

| Chromatic | 月5,000 snapshot無料 | 約$149〜$649 |

| Percy | 月5,000 snapshot無料 | 約$199+ |

| Applitools | 評価版 | enterprise quote |

| Cypress Cloud | 月500結果無料 | 約$75〜$300+ |

| MSW | 無料 | — |

| Loki / BackstopJS / Reg-Suit | 無料 | — |

小規模チームの出発点は単純だ — Vitest + Playwright + Chromatic無料tier。ここから始めてチームが大きくなればStorybook 9をデザインシステム中心に、ビジュアルリグレッションを有料tierに、そしてPlaywright MCPを導入して新規テスト作成速度を上げるのが標準ルート。

おわりに — 「ツールを買うのではなく、信頼を買うのだ」

2026年のフロントエンドテスティング市場は単一ツールのトーナメントではなく4軸の合奏だ。そして次の5つの流れが市場を揺らしている。

1. **Playwrightの標準化** — 新規E2Eの70%+シェア。時間が経つほど格差拡大。

2. **Vitestの台頭** — Viteエコシステムと共に事実上の標準ユニットランナー。

3. **Storybook 9の軽量化** — デザインシステム + コンポーネントテスト + ビジュアルリグレッションのハブ。

4. **AIエージェントが直接テスト作成** — Playwright MCP、Browser MCPが日常化。

5. **MSWの標準化** — ネットワークモッキング = MSW。ツール独立なfixture。

小規模チームの初行 — `npm i -D vitest @testing-library/react @playwright/test msw`。この4つで95%のケースがカバーされる。次のステップがStorybook 9 + Chromatic、その次がPlaywright MCP統合。

一つの真理 — **「ツールを買うのではなく、信頼(テストが壊れた時に本当にバグを捕まえるという信頼)を買うのだ」**。どのツールを選んでもその信頼が90%未満なら、そのテストはPRを遮断するノイズに過ぎない。ツール評価の最初の質問は常に「このテストが赤線を出した時、実際にバグを捕まえた比率は?」だ。

参考 / References

- Playwright — [https://playwright.dev/](https://playwright.dev/)

- Playwright VS Code Extension — [https://playwright.dev/docs/getting-started-vscode](https://playwright.dev/docs/getting-started-vscode)

- Playwright Trace Viewer — [https://playwright.dev/docs/trace-viewer](https://playwright.dev/docs/trace-viewer)

- Playwright Component Testing — [https://playwright.dev/docs/test-components](https://playwright.dev/docs/test-components)

- Playwright MCP — [https://github.com/microsoft/playwright-mcp](https://github.com/microsoft/playwright-mcp)

- Cypress — [https://www.cypress.io/](https://www.cypress.io/)

- Cypress 14 release notes — [https://docs.cypress.io/guides/references/changelog](https://docs.cypress.io/guides/references/changelog)

- Cypress Cloud — [https://www.cypress.io/cloud](https://www.cypress.io/cloud)

- Vitest — [https://vitest.dev/](https://vitest.dev/)

- Vitest Browser Mode — [https://vitest.dev/guide/browser/](https://vitest.dev/guide/browser/)

- Jest — [https://jestjs.io/](https://jestjs.io/)

- Jest 30 announcement — [https://jestjs.io/blog/2025/06/04/jest-30](https://jestjs.io/blog/2025/06/04/jest-30)

- Testing Library — [https://testing-library.com/](https://testing-library.com/)

- React Testing Library — [https://testing-library.com/docs/react-testing-library/intro/](https://testing-library.com/docs/react-testing-library/intro/)

- Storybook — [https://storybook.js.org/](https://storybook.js.org/)

- Storybook 9 release — [https://storybook.js.org/blog/storybook-9/](https://storybook.js.org/blog/storybook-9/)

- Storybook Vitest addon — [https://storybook.js.org/docs/writing-tests/test-addon](https://storybook.js.org/docs/writing-tests/test-addon)

- Chromatic — [https://www.chromatic.com/](https://www.chromatic.com/)

- Percy — [https://percy.io/](https://percy.io/)

- Applitools — [https://applitools.com/](https://applitools.com/)

- Applitools Visual AI — [https://applitools.com/platform/visual-ai/](https://applitools.com/platform/visual-ai/)

- Loki (Storybook visual regression) — [https://loki.js.org/](https://loki.js.org/)

- BackstopJS — [https://github.com/garris/BackstopJS](https://github.com/garris/BackstopJS)

- Reg-Suit — [https://github.com/reg-viz/reg-suit](https://github.com/reg-viz/reg-suit)

- Selenium — [https://www.selenium.dev/](https://www.selenium.dev/)

- WebdriverIO — [https://webdriver.io/](https://webdriver.io/)

- MSW (Mock Service Worker) — [https://mswjs.io/](https://mswjs.io/)

- Model Context Protocol — [https://modelcontextprotocol.io/](https://modelcontextprotocol.io/)

- State of JS 2024 — [https://stateofjs.com/](https://stateofjs.com/)

- Kent C. Dodds — Testing Trophy — [https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications](https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications)

- メルカリ Engineering Blog — [https://engineering.mercari.com/blog/](https://engineering.mercari.com/blog/)

- トス技術ブログ — [https://toss.tech/](https://toss.tech/)

- カカオ技術ブログ — [https://tech.kakao.com/](https://tech.kakao.com/)

현재 단락 (1/551)

2018年頃に「フロントエンドのテストは何を使う?」と聞けば、答えはシンプルだった。ユニットはJest、E2EはSeleniumかCypress、ビジュアルリグレッションは気合のある人だけBackst...

작성 글자: 0원문 글자: 24,165작성 단락: 0/551