• #vitest
  • #playwright
  • #coverage
  • #e2e
  • #テスト
  • #mdx-playground
  • #日記
開発mdx-playgroundメモ

Vitest・Playwright テスト環境整備

朝、pnpm test を叩いたら36ファイル中29しかパスしていなかった。赤いバツが7つ並ぶターミナルを見て、今日はテストを全部通すまで他のことをしないと決めた。結果、夜には全34ファイル・14,817テストが緑のチェックマークに変わった。

e2eテストがVitestに拾われる問題

最初に気づいたのは、Playwright用のe2eテストファイルがVitestの対象に含まれていたこと。e2e/*.spec.ts をVitestが読みに行き、Playwrightのインポートで即座にコケる。

vitest.config.tsexclude'**/e2e/**' を追加して分離した。

// vitest.config.ts
test: {
  exclude: [
    '**/node_modules/**',
    '**/dist/**',
    '**/e2e/**',  // playwright e2e tests
  ],
}

これだけで36ファイル中31パスまで回復した。

失敗テストの修正

残り5ファイルの失敗原因を一つずつ潰していった。データ構造の変更に追従できていないアサーションの修正、インポートパスのずれなど、どれも「コード本体は正しいのにテストが古い」パターンだった。

@vitest/coverage-v8 の導入

カバレッジを測るために @vitest/coverage-v8 をインストールした。最初に入れたバージョンがVitestのバージョンと一致せずエラーが出た。Vitestとcoverage-v8は同じバージョンに揃える必要がある。

pnpm add -D @vitest/coverage-v8@<vitestと同じバージョ>

バージョンを揃えた瞬間、カバレッジレポートが正常に出力された。

Vue SFCのパースエラー

カバレッジ対象にデフォルト設定のまま走らせると、Vue SFC(.vueファイル)をv8がパースしようとしてエラーの山が出た。.vue のカバレッジ計測はViteの変換パイプラインとの兼ね合いで一筋縄ではいかない。

今回はロジック層の品質が知りたかっただけなので、カバレッジ対象を .ts ファイルのみに絞った。

coverage: {
  provider: 'v8',
  include: [
    'app/utils/**/*.ts',
    'app/composables/**/*.ts',
  ],
}

utils/composables/ 配下のTypeScriptファイルだけを計測対象にすることで、パースエラーが消え、測りたいロジックのカバレッジだけが見えるようになった。

カバレッジ改善のためのテスト追加

レポートを眺めると、テストが薄い箇所がいくつか見つかった。テスト容易なユーティリティ3ファイルを選び、テストを並列で作成した。

対象は以下のようなファイル群。

  • 仕訳データの変換ロジック
  • 伝票マッピングのユーティリティ
  • ウォーターフォールチャートの座標計算

いずれも純粋関数で、外部依存がなく、入力と出力の関係が明確。テストを書き始めてから実行まで手が止まらなかった。

Playwright e2eテスト登録

Playwrightのe2eテストを3ファイル・16テストケースで構成した。

  • navigation.spec.ts - ナビゲーション・ブレッドクラムの動作
  • blog-calendar.spec.ts - ブログカレンダーの表示と操作
  • content.spec.ts - コンテンツページの描画確認

Vitestのユニットテストとは実行パスを完全に分けているので、pnpm test でユニットテストだけが走り、e2eは pnpm exec playwright test で別途実行する。

ベンチマーク実行

テストが全パスした後、ベンチマーク実行も完了した。パフォーマンスのベースラインを取っておくことで、今後のリファクタリング時に速度劣化を検知できる。

最終結果

全34ファイル、14,817テストが全パス。朝の29/36から始めて、e2e分離、失敗テスト修正、カバレッジ導入、テスト追加と積み上げて、最終的にテストスイート全体が緑になった。

振り返り

カバレッジ設定で一番時間を食ったのはVue SFCのパースエラーだった。「全ファイルのカバレッジを測りたい」と欲張ると設定の沼にはまる。まず .ts だけに絞って数字を出し、必要になったら .vue を追加する。最初から完璧を狙わず、測れる範囲から測る方が前に進む。

@vitest/coverage-v8 のバージョン不一致も、エラーメッセージを読めば30秒で解決する話だが、「とりあえず最新版を入れる」癖がついていると踏む。VitestとそのプラグインはSemVerが揃っていないと動かない。package.json のVitestバージョンを確認してからインストールする、この一手間で時間を節約できる。