はじめに
プログラミング言語をとわず設定ファイルは難しいですよね ドキュメントを見ても何ができるのかわからず検索でたまたま見つけた設定ファイルをコピペしては試し...を繰り返していると思います。わたしは Webpack で痛い思いをしたので本記事では設定ファイルを少なく、ドキュメントを引用して再現性を高くすることを意識して Vite で作った React プロジェクトに最小構成の Jest を導入します。
環境構築
プロジェクト作成
TypeScript + React で作成してください。
npm create vite@latest
Jest
テストフレームワークは Jest を選択したのでインストールします。
npm install --save-dev jest
必要なパッケージは次の ts-jest
から順にスクロールしながら進めると OK です。
ts-jest
Jest を TypeScript で動かすためのプリプロセッサです。このプリプロセッサでは TypeScript で書いた Jest テストを JavaScript に変換する役割があります。
npm install --save-dev ts-jest
インストールするだけでは有効にならず設定ファイル( jest.config.ts
)が必要になります。コマンド実行時には jest.config.js
が作成されるので TypeScript ファイルに変換しましょう(変換する必要はありませんが、統一したいので変換しています)
npx ts-jest config:init
jest.config.ts で考えること
- .js を .ts に変換する
- preset は
"ts-jest"
とする- transformer は preset の指定をすると内部で設定されるので省略
- testEnvironment は DOM 環境をブラウザで動いてるかのようにみせるため
jsdom
に変換
import type {Config} from 'jest';
const config: Config = {
preset: "ts-jest",
testEnvironment: "jsdom",
};
export default config;
jest.config.js
は次のような内容になっています。
/** @type {import('ts-jest').JestConfigWithTsJest} **/
export default {
testEnvironment: "node",
transform: {
"^.+.tsx?$": ["ts-jest",{}],
},
};
npx jest --init
も良いのですが TypeScript の項目を上書きすることになるので npx ts-jest config:init
が楽です
jest-environment-jsdom
testEnvironment
に jsdom
が指定してあります。jsdom
はコンポーネントがブラウザで動いてるかのように DOM 環境を提供するパッケージです。
npm install --save-dev jest-environment-jsdom
@types/jest
TypeScript を選択すると型定義した Jest API( descripbe
や expect
)が必要になります。サードパーティのパッケージ @types/jest
が必要になります。
npm install --save-dev @types/jest
@jest/globals
も良いのですが必要な関数を import で取り込む必要があるので @types/jest が推奨されています
ts-node
Jest の実行に ts-node
が必要です。
npm install --save-dev ts-node
もしインストールせず Jest を実行すると次のエラーになります。
Error: Jest: Failed to parse the TypeScript config file /Users/akira/Project/private/vite-ts/jest.config.ts
Error: Jest: 'ts-node' is required for the TypeScript configuration files. Make sure it is installed
React Testing Library
Jest で React コンポーネントのテストを作成するのに必要です。
npm install --save-dev @testing-library/react @testing-library/dom @types/react @types/react-dom
jest-dom
インストール
React コンポーネントのテストに必要なカスタムマッチャーを追加します。
npm install --save-dev @testing-library/jest-dom
jest-dom
を有効にするにはテストファイルの中で import する必要がありますが都度、テストファイルに追加する必要がありとても手間です。Jest には setupFilesAfterEnv
を使ってセットアップのスクリプトを指定することが出来るのでそれを利用します。また、公式ドキュメントによると tsconfig.json で include
に指定する必要があります。
URL: https://github.com/testing-library/jest-dom?tab=readme-ov-file#with-typescript
jest.config.ts で考えること
- vite で作った tsconfig.json は project references を使っている
- Jest では project references で参照するファイルの内容までみない
- Jest で必要な tsconfig を新しく作成して transform で指定する
- tsconfig.jest.json として tsconfig.app.json からコピペ
- setupFilesAfterEnv にセットアップスクリプトを指定する
- jest.setup.ts として jest-dom を import で呼び出す
diff --git a/jest.config.ts b/jest.config.ts
index 95b57b9..c99ca4d 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -2,6 +2,12 @@ import type {Config} from 'jest';
const config: Config = {
preset: "ts-jest",
+ transform: {
+ "^.+.tsx?$": ["ts-jest", {
+ tsconfig: "tsconfig.jest.json"
+ }],
+ },
+ setupFilesAfterEnv: ['./jest.setup.ts'],
testEnvironment: "jsdom",
};
公式ドキュメントにある構造だと WARN になります。
// jest.config.js
module.exports = {
// [...]
globals: {
'ts-jest': {
tsConfig: 'tsconfig.test.json'
}
}
};
URL: https://huafu.github.io/ts-jest/user/config/tsConfig#path-to-a-tsconfig-file
WARN メッセージ
ts-jest[ts-jest-transformer] (WARN) Define `ts-jest` config under `globals` is deprecated. Please do
transform: {
<transform_regex>: ['ts-jest', { /* ts-jest config goes here in Jest */ }],
},
jest.setup.ts で考えること
ここは jest-dom を import を使って呼び出すだけで OK です。
import "@testing-library/jest-dom"
tsconfig.jest.json で考えること
- tsconfig.app.json をコピペして include にセットアップスクリプトを指定する
- テストだけなら不要な設定が多いかも(要ブラッシュアップ)
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "jest.setup.ts"]
}
パッケージの追加、設定はここまでです。
アセット
Jest は Webpack などバンドラといっしょに動くわけではないので svg / css を理解することができません。そのため、moduleNameMapper
を使ってマッチした拡張子に対してスクリプトを実行することができます。
svg / css があったとしてもコンポーネントの振る舞いに影響がないので module.exports = {};
を実行するだけで OK です。
module.exports = {};
module.exports = {};
diff --git a/jest.config.ts b/jest.config.ts
index c99ca4d..624a38a 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -7,6 +7,10 @@ const config: Config = {
tsconfig: "tsconfig.jest.json"
}],
},
+ moduleNameMapper: {
+ "\\.svg": "<rootDir>/tests/__mocks__/fileMock.ts",
+ "\\.css": "<rootDir>/tests/__mocks__/styleMock.ts",
+ },
setupFilesAfterEnv: ['./jest.setup.ts'],
testEnvironment: "jsdom",
};
テストを動かしてみる
import { render, screen } from "@testing-library/react"
import App from "../src/App.tsx"
test("render App component", async () => {
render(<App />)
const h1 = screen.getByRole("heading")
expect(h1).toHaveTextContent("Vite + React")
})
これを npm run test
から実行してみてください。きっとパスするはずです。
気づき
TypeScript で動かそうと思うと Jest 以外のパッケージに依存して、かつ初期化の方法が複数あったりとかなりドキュメントを読み込まないと理解することができませんでした。
リポジトリ
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼