テスト改善 — Jest → Vitest に移行

はじめに

はじめまして。フロントエンドエンジニアをしている伊藤と申します。

私はプロダクトの動作を保証するものとして、テストは欠かせないものだと思っています。
私が所属するチームのプロダクトでも以下のテストを行なっています。

  • テストフレームワークを利用したユニット/コンポーネントテスト
  • クラウドサービスを利用したE2Eテスト
  • QA

その中で、私が一番関わりが深いのは、テストフレームワークです。現在のチームに参画した時から、チームの JavaScript テストフレームワークは Jest が使われており、長年苦楽を共にしてきました。ただ、そんな親友の Jest ともついにお別れする時がきてしまいました。

本記事では、 経緯などを踏まえて、Jest → Vitest への移行について紹介していきます。

基本知識・用語の確認

JavaScript コードの品質と信頼性を確保するために、テストの作成・実行・検証・分析を一つで完結できるように設計された便利なツール

モダンな JavaScript/TypeScript プロジェクトの開発とビルドを、信じられないほど速く、シンプルに、そして効率的に行うための次世代ツール

Vite の高速性を活かし、Jest と高い互換性を持つことで、開発者体験とテスト効率を大幅に向上させるJavaScript/TypeScript向けの新しいテスティングフレームワーク

1. なぜ移行をしたのか

1.1 テストの実行時間がとにかく長い

所属するチームでは、Git のワークフローを使用しています。特定のブランチに向けて PR が作成されるとワークフローが開始されます。そのワークフロー内で、Jest で記述されたテストを実行しています。
ただ、そのテストの完了までがとにかく長いです。平均して15分ほどかかっていました。DevUX の観点からすると、とんでもない悪影響です。

  • 開発者の満足度低下
  • 生産性やイテレーション速度の低下
  • バグ発見の遅れ
  • コード品質への影響

1.2 Nuxt3移行に伴うビルド&テスト環境の統一

Vue2/Nuxt2 から Vue3/Nuxt3 へ移行した際、ビルドツールについても変更を行いました。
Nuxt3 では標準で Vite が採用されているため、Webpack から Vite へ切り替えています。
ただし、テスト環境は従来どおり Jest(Webpackベース)を利用しており、本番環境との間に差異が残っていました。

そこで、より実行環境に近い形でテストを行えるように、Nuxt3と親和性の高いVitestへ移行が必要でした。
上記を解決することで、環境の一貫性が保たれ、テストの信頼性も向上すると考えました。

1.3 テストコードの見直しが必要

私が参画した後もテストコードは増えていく一方でした。
どんなテスト内容か、最適なテストができているかなどは年々不透明になっていました。
潜在的な課題とはなっていましたが、テストコードを見直すことは、他の新規開発を優先してしまったため、後回しになっていました。

2. Vitest を選んだ理由

2.1 手軽

Vitest は Vite がないプロジェクトでも活用することができます。
手軽に勧められる点がポイントです。

2.2 フロントエンドロードマップの Testing に変化

フロントエンドエンジニアが学ぶべきロードマップの中に、Testing という項目があります。
おそらく Jest を勧めていた箇所が、Vitest に変わっていました。
https://roadmap.sh/frontend

2.3 Jest との互換性も問題なし

下記の表は、簡単に Jest と Vitest を比較したものです。
比較をして、Vitest への移行をしても問題ないと思いました。
(独自で調べた内容で作成したため、誤っている場合もあります)
Comparison table between Jest and Vitest testing frameworks

3. 実装

3.1 Vitest

1. Vitest をインストール

npm install -D vitest

2. Vitest の設定ファイルを追加

Vite を使っているプロジェクトなら、vite.config.ts に設定を記述
使っていない場合は、vitest.config.ts を新規作成
(下記は、弊社の例です。)

```
/// 
import path from 'path';

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

import { config } from 'dotenv';

// .env.test を明示的に読み込む
config({ path: path.resolve(__dirname, 'src/.env.test') });

export default defineConfig(() => {
    return {
        plugins: [vue()],
        resolve: {
            alias: {
                vue: 'vue/dist/vue.esm-bundler.js',
                '@@': `${__dirname}`,
                '@': `${__dirname}/src`,
            },
        },
        test: {
            setupFiles: ['src/tests/setup.ts'],
            include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
            exclude: ['node_modules'], // テスト対象から除外するパターン
            environment: 'jsdom',
            globals: true,
            environmentOptions: {
                jsdom: {
                    url: 'http://localhost/', // 必要であれば設定
                },
            },
            cache: true,
        },
    };
});

```
3. Jest で記述されている箇所を、vi に変更する

一括変換でもいいですし、AI エージェントに任せるのも手です。
jest change vi

4. テストで使用する環境変数の読み込み

テスト用の環境変数を用意している場合は、vite.config.ts にその旨を記載します。

// .env.test を明示的に読み込む
config({ path: path.resolve(__dirname, 'src/.env.test') });  
5. エラーの解消

mock を使用している箇所でエラーが出たので解消しました。
(エラー内容:mock を使うなら、一番最初の行に記述してください。)

Error: [vitest] There was an error when mocking a module. If you are using “vi.mock” factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock

6. テストを成功させる

success test

7. Jest で使っていた記述を削除する

jest.config.ts など、Jest 関連のものを削除します。

4. 結果

テストの実行時間の大幅な短縮ができました。
Vitest への移行と、既存の不要テストの削除による成果だと思います。
以前まで、15分かかっていたテストが5分で終了するようになりました。
おかげでリリースまでの時間も縮小することができました。
もしかすると、Vitest への移行だけでここまで縮小することはなかったかもしれませんが、
プラスの成果はあったと思います。

まとめ

Jest → Vitest 移行を行なったことで一番の収穫は、既存のテストを見直す機会を得たことです。
どうしても新規開発をしていると、テストコードにまで気が回らなくなってしまいます。
その結果、放置されてしまっていて、テスト内容が適正かなどの判断が後回しになっていました。

ただ、今回の移行でテストコードの見直しをするきっかけをもらったと思います。
AI を使った開発により、テストコードでテストしたいことが実現しやすくなりました。
本記事が、皆様の関わっているプロジェクトのテストコードを見直すきっかけになれば幸いです。
これからもより良いテストコードを目指していきます。




Source link

関連記事

コメント

この記事へのコメントはありません。