Vite × Vitest × React Testing Library環境構築

こんにちは。私は主にReactでWEBフロントエンド開発を行っています。

機能が多く複雑なNext.jsではなく、Viteを用いたシンプルな構成のReactプロジェクトを立ち上げることも多いです。

そういったプロジェクトにコンポーネントテストを導入する際、環境構築に手間取ることが多かったので、この記事でその方法を紹介します。

手順

2024年8月現在、Viteを使ったReactプロジェクトを立ち上げる方法についてです。

テストツールとしてVitestReact Testing Libraryを使います。

ViteによるReact環境構築

template部分はreact-swc-tsとしたSWCを使う環境構築でも良いです。

npm create vite@latest -- --template react-ts を実行し、お好みのプロジェクト名を入力して、プロジェクトを作成します。

パッケージのインストール

npm i -D vitest @testing-library/react @testing-library/dom @testing-library/jest-dom @testing-library/user-event @types/react @types/react-dom jsdom を実行します。

これによりVitest、React Testing Library、それらのTSパッケージのインストールが完了します。

TypeScriptの設定ファイルの修正

./tsconfig.app.jsonを以下のように修正します。

{
  "compilerOptions": {
    "types": ["vitest/globals"] // 追加
  },
  "include": ["src", "vitest.setup.ts"] // vitest.setup.tsを追加
}

Vitestの公式ページにあるようにVitestでTypeScriptを効かせるためにtypesを追加しました。

includeにファイルを追加することで、後ほど追加するvitest.setup.tsファイルもこちらのtsconfigの設定が効くようになりました。

ちなみに、少し古いViteで立ち上げたプロジェクトの場合tsconfig.app.jsonが存在しないと思いますが、その場合はtsconfig.jsonに上記の設定を加えればOKです。

Vitestのセットアップファイルの作成

こちらのセットアップファイルは必須ではありませんが、すべてのファイルに書き込むのは大変なので、作成しておいた方が良いと思います。

以下の./vitest.setup.tsを作成します。

import { cleanup } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import '@testing-library/jest-dom';

export const user = userEvent.setup();

afterEach(() => {
  cleanup();
});

VitestはJestと違いcleanup処理を自動で行ってくれないため、毎テストごとに行うように記述しました。

またReact Testing Libraryの公式ページにあるようにuserをあらかじめセットアップしてから使った方が良いとのことなので、こちらのファイルでセットアップを行いました。

Viteの設定ファイルの修正

以下のように./vite.config.tsを修正します。

/// <reference types="vitest" />
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' // @vitejs/plugin-react-swcでもOK

export default defineConfig({
  plugins: [react()],
  test: {
    environment: "jsdom", // 代わりにhappy-domをインストールして使うことも可能
    globals: true,
    setupFiles: "./vitest.setup.ts"
  }
})

Vitestの公式ページにあるようにトリプルスラッシュディレクティブを用いてVitestの型を読み込むようにしました。

また、各テストファイルでvitestをインポートしなくて済むようにglobalsの設定も追加しています。こちらの設定が不要の場合はTypeScriptの設定ファイルのtypesの設定も外してください。

環境構築完了

ここまでで環境構築は完了しています。動作確認のため以下のファイルを追加してテストを実行してみましょう。

ちなみに私はVS Codeを使ってこちらの環境構築を行いましたが、TSエラーが出続けている場合はコマンドパレットからTypeScript: Restart TS Serverを実行することでエラーが消えました。

動作確認と追加設定

動作確認

以下のように./src/App.test.tsxを作成します。

import { render, screen } from '@testing-library/react'
import { user } from '../vitest.setup'
import App from './App'

beforeEach(() => {
  render(<App />)
})

test('Vite + Reactが表示されている', () => {
  expect(screen.getByText('Vite + React')).toBeInTheDocument()
})
test('"count is 0"ボタンが表示されている', () => {
  expect(screen.getByRole('button', { name: 'count is 0' })).toBeInTheDocument()
})
test('"count is 0"をクリックするとインクリメントされる', async () => {
  await user.click(screen.getByRole('button', { name: 'count is 0' }))
  expect(screen.getByRole('button', { name: 'count is 1' })).toBeInTheDocument()
})

表示の確認やボタンクリックのテストを簡単に行うテストファイルを作成しました。

こちらのファイルを実行するためにnpx vitestを実行してください。全てパスしていれば環境構築は上手くいっています。

テスト結果を見やすくするための追加設定

ここまでで環境構築と動作確認は済んでいますが、Vitestのテスト結果をよりわかりやすく確認するためにもう一つパッケージを追加します。

npm i -D @vitest/ui を実行して、./package.jsonを以下のように修正してください。

{
  "scripts": {
    "test": "vitest --ui" // 追加
  }
}

最後にnpm run testを実行してテスト結果をブラウザで確認出来たら完了です。お疲れさまでした。

実行結果の画像

まとめ

Viteを使って立ち上げたReact × TypeScriptのプロジェクトにVitestとReact Testing Libraryを導入する手順をまとめました。これからテスト環境を構築しようと考えている方のお役に立てれば幸いです。

おわりに

KENTEMでは、様々な拠点でエンジニアを大募集しています!
建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。
recruit.kentem.jp career.kentem.jp