😃
Next.jsでJestをセットアップしよう!
コードの信頼性を高める上でテストは不可欠なものです。フロントエンド開発においてもこの重要性は変わりません。しかし、テスト環境のセットアップはちょっとした壁かもしれません。
そこで今回は Next.js で Jest をセットアップする手順を紹介します。
前提
$ sw_vers
ProductName: macOS
ProductVersion: 13.0
$ node -v
v20.11.0
$ pnpm -v
8.15.1
$ pnpm next -v
Next.js v14.1.0
セットアップ
1. テスト用アプリケーションの作成
テスト対象の Next.js アプリケーションを作ります。
$ pnpm create next-app
../Library/pnpm/store/v3/tmp/dlx-18079 | Progress: resolved 1, reused 0, downl../Library/pnpm/store/v3/tmp/dlx-18079 | +1 +
../Library/pnpm/store/v3/tmp/dlx-18079 | Progress: resolved 1, reused 0, downl../Library/pnpm/store/v3/tmp/dlx-18079 | Progress: resolved 1, reused 1, downloaded 0, added 1, done
✔ What is your project named? … test-example
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … No
✔ Would you like to use Tailwind CSS? … No
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to customize the default import alias (@/*)? … No
Creating a new Next.js app in /Users/nabe/work/test-example.
Using pnpm.
Initializing project with template: app
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
Packages: +28
++++++++++++++++++++++++++++
Progress: resolved 36, reused 28, downloaded 0, added 28, done
dependencies:
+ next 14.1.0
+ react 18.2.0
+ react-dom 18.2.0
devDependencies:
+ @types/node 20.11.20
+ @types/react 18.2.58
+ @types/react-dom 18.2.19
+ typescript 5.3.3
Done in 2.9s
Initialized a git repository.
Success! Created test-example at /Users/nabe/work/test-example
2. パッケージのインストール
UI コンポーネントのテストに必要なパッケージをインストールします。
pnpm install -D jest \
@types/jest \
jest-environment-jsdom \
@testing-library/react \
@testing-library/jest-dom \
@testing-library/user-event
Jest 以外の各パッケージの役割は以下の通りです。
パッケージ | 役割 |
---|---|
@types/jest | expect や test などの型を import 無しで参照できるようにする |
jest-environment-jsdom | テストの実行環境で DOM API シミュレートする |
@testing-library/react | レンダリングなどReactコンポーネントをテストするための機能を提供する |
@testing-library/jest-dom | UI コンポーネントの検証に便利な機能を Jest に追加する |
@testing-library/user-event | ユーザー操作をシミュレートする |
package.json
{
"name": "test-example",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest"
},
"dependencies": {
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"typescript": "^5"
}
}
3. 設定ファイルの生成
基本的な Jest 設定ファイルを生成します。
後で Next.js で動作するために必要なオプションをここに追加します。
pnpm create jest@latest
.../Library/pnpm/store/v3/tmp/dlx-14502 | +237 ++++++++++++++++++++++++
.../Library/pnpm/store/v3/tmp/dlx-14502 | Progress: resolved 237, reused 237, downloaded 0, added 237, done
The following questions will help Jest to create a suitable configuration for your project
✔ Would you like to use Jest when running "test" script in "package.json"? … yes
✔ Would you like to use Typescript for the configuration file? … no
✔ Choose the test environment that will be used for testing › jsdom (browser-like)
✔ Do you want Jest to add coverage reports? … yes
✔ Which provider should be used to instrument code for coverage? › babel
✔ Automatically clear mock calls, instances, contexts and results before every test? … yes
✏️ Modified /Users/nabe/work/next-test-example2/package.json
📝 Configuration file created at /Users/nabe/work/next-test-example2/jest.config.js
4. セットアップファイルの作成
各テストファイルのコードを実行する前に、テスト環境に jest-dom
をインポートしてUIコンポーネントの検証ができるようマッチャーを拡張します。
jest.config.js
の setupFilesAfterEnv
にこのファイルのパスを指定するとテストファイルごとにセットアップファイルのコードが1回実行されるようになります。パスの指定はこの後の手順で行います。
jest.setup.ts
import '@testing-library/jest-dom';
5. 設定ファイルの編集
next/jest
を使うように設定ファイルを更新します。
Jest が Next.js で動作するために必要なオプションが設定されます。
jest.config.js
/**
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/configuration
*/
+ const nextJest = require('next/jest');
+ const createJestConfig = nextJest({
+ // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
+ dir: './',
+ });
/** @type {import('jest').Config} */
const config = {
// ...
// A list of paths to modules that run some code to configure or set up the testing framework before each test
+ setupFilesAfterEnv: ['./jest.setup.ts'],
- // setupFilesAfterEnv: [],
// ...
// The test environment that will be used for testing
+ testEnvironment: 'jest-environment-jsdom',
- testEnvironment: 'jsdom'
// ...
}
+ module.exports = createJestConfig(config);
- module.exports = config;
動作確認
単純なコンポーネントを使って実際にテストしてみましょう。
テスト対象
src/components/Form.tsx
type Props = {
name: string;
onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
};
export const Form = ({ name, onSubmit }: Props) => {
return (
<form
onSubmit={(event) => {
event.preventDefault();
onSubmit?.(event);
}}
>
<h2>アカウント情報</h2>
<p>{name}</p>
<div>
<button>編集する</button>
</div>
</form>
);
};
テストコード
src/components/Form.test.tsx
import { fireEvent, render, screen } from '@testing-library/react';
import { Form } from './Form';
test('名前を表示すること', () => {
render(<Form name="john" />);
expect(screen.getByRole('button')).toBeInTheDocument();
});
test('ボタンをクリックすると、イベントハンドラーが呼ばれること', () => {
const mockFn = jest.fn();
render(<Form name="john" onSubmit={mockFn} />);
fireEvent.click(screen.getByRole('button'));
expect(mockFn).toHaveBeenCalled();
});
テスト結果
pnpm test
> test-example@0.1.0 test /Users/nabe/work/test-example
> jest
PASS src/components/Form.test.tsx
✓ 名前を表示すること (29 ms)
✓ ボタンをクリックすると、イベントハンドラーが呼ばれること (8 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
Form.tsx | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.619 s, estimated 1 s
Ran all test suites.
まとめ
この記事では、Next.jsでJestをセットアップする手順を紹介しました。
- テスト用の Next.js アプリケーションを作成し、必要なパッケージをインストールしました
- Jestの設定ファイルを生成し、Next.jsで動作するためのオプションを追加しました
- 単純なコンポーネントを使ってテストを実行し、成功したことを確認しました
Discussion