はじめに
Vite + React + TypeScriptのプロジェクトにJestとtesting-libraryを導入してテストを書く手順をまとめます。
手順
1. Jestをインストールする
$ npm i --save-dev jest
$ npm i --save-dev @types/jest
$ npm i --save-dev ts-jest
$ npm i --save-dev identity-obj-proxy
$ npm i dotenv
-
jest:JavaScript/TypeScriptのテストフレームワーク本体 -
@types/jest:JestのTypeScript用の型定義。これがないとTypeScriptがJestの関数(describe、test、expectなど)を認識できない -
ts-jest:TypeScriptをJavaScript(CommonJS)に変換してJestで実行できるようにするパッケージ -
identity-obj-proxyは、インポートされた CSS モジュールの各クラス名をそのまま文字列として返すモックオブジェクトを提供し、コンポーネントが適用するクラス名の存在などをテストできるようになる -
dotenv:jest.setup.tsで.envファイルの環境変数を読み込むために使用
2. Jest用のtsconfigを作る
ルート配下(package.jsonと同じ階層)に tsconfig.jest.json を作成します。
ViteはESNext(ESM)、JestはCommonJSというモジュールシステムの違いがあるため、Jest専用のtsconfigを分ける必要があります。
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "Node",
"verbatimModuleSyntax": false
}
}
-
extends:tsconfig.app.jsonの設定を継承する。共通の設定を書き直す必要がなくなる -
module:モジュールシステムの方式を指定。JestはCommonJSで動くため"CommonJS"を指定する -
moduleResolution:モジュールの探し方を指定。CommonJSに合わせて"Node"を指定する -
verbatimModuleSyntax:import/exportの書き方を厳密にチェックする設定。CommonJS環境ではESMのimport文と衝突するためfalseにする
3. jest.config.jsを作る
ルート配下に jest.config.js を作成します。
export default {
// ts-jestのプリセットを使用する
preset: "ts-jest",
// テスト環境をjsdom(ブラウザ相当)にする。ReactのDOM操作をテストするために必要
testEnvironment: "jsdom",
// テスト実行前に読み込むセットアップファイルを指定
setupFilesAfterEnv: ["./jest.setup.ts"],
// テスト対象のファイルパターンを指定。__tests__フォルダ内の.spec.ts/.spec.tsxのみ対象にする
transform: {
// .ts/.tsxファイルをts-jestで変換する
// デフォルトではtsconfig.jsonが読み込まれるが、Viteプロジェクトではモジュール方式の違いでエラーが出るため
// Jest専用のtsconfig.jest.jsonを指定する
"^.+\\.(ts|tsx)$": ["ts-jest", {
tsconfig: "tsconfig.jest.json",
}],
},
moduleNameMapper: {
// CSSファイルのimportをモック(代替)する。JestはCSSを解釈できないため、ダミーに置き換える
"\\.(css|less)$": "identity-obj-proxy",
},
};
4. jest.setup.tsを作る
ルート配下に jest.setup.ts を作成します。テスト実行前に必要な初期設定をまとめるファイルです。
import "@testing-library/jest-dom";
// .envファイルの環境変数を読み込む
import { config } from "dotenv";
// dotenvで.envファイルを読み込む。quiet: trueでログ出力を抑制する
config({ quiet: true });
5. tsconfig.app.jsonを変更する
compilerOptionsの types に "node", "jest", "@testing-library/jest-dom" を追加します。
これにより、TypeScriptがJestやtesting-libraryの型を認識できるようになります。
{
"compilerOptions": {
"types": ["vite/client", "node", "jest", "@testing-library/jest-dom"],
},
}
6. react-testing-libraryの導入
$ npm i --save-dev @testing-library/react
$ npm i --save-dev @testing-library/jest-dom
$ npm i --save-dev jest-environment-jsdom
$ npm i --save-dev @testing-library/user-event
-
@testing-library/react:Reactコンポーネントをテスト上でレンダリングするためのライブラリ -
@testing-library/jest-dom:toBeInTheDocument()などのDOM用カスタムマッチャーを追加する -
jest-environment-jsdom:Jest上でブラウザ環境(DOM操作)を再現するためのパッケージ -
@testing-library/user-event:クリックや入力などのユーザー操作をシミュレートするためのライブラリ
7. package.jsonにtestスクリプトを追加する
package.jsonの scripts に "test": "jest" を追加します。
"scripts": {
"test": "jest"
}
これにより npm run test でJestが実行できるようになります。
8. テストファイルを作成する
src/__tests__/ フォルダを作成し、テストファイルを作成します。
テストファイルの命名規則は 〇〇.spec.tsx です。
// テスト対象のコンポーネントをインポート
import App from "../App";
// render: コンポーネントを仮想DOMにレンダリングする
// screen: レンダリングされた画面の要素を取得する
import { render, screen } from "@testing-library/react";
// describe: テストをグループ化する
describe("App", () => {
// test: 個別のテストケースを定義する
test("タイトルがあること", () => {
// Appコンポーネントをレンダリング
render(<App />);
// "Hello World" というテキストがDOM上に存在することを確認
expect(screen.getByText("Hello World")).toBeInTheDocument();
});
});
9. テスト実行
$ npm run test
テストが通れば成功です。