Vitest と Happy DOM を使用した React コンポーネントのテスト環境構築
React アプリケーションのテストを Vitest
と Happy DOM
を使用して行う手順を、以下の流れで説明します。
1. 必要なライブラリのインストール
まず、テストに必要なライブラリをインストールします。
コマンド
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event happy-dom
ライブラリの説明
-
vitest
: 高速なテストランナー。 -
@testing-library/react
: React コンポーネントのテストを支援。 -
@testing-library/jest-dom
: DOM に関するカスタムマッチャーを提供。 -
@testing-library/user-event
: ユーザー操作(クリックなど)のシミュレーションをサポート。 -
happy-dom
: 軽量で高速なブラウザエミュレーション環境。
2. React コンポーネントの作成
テスト対象となる簡単なボタンコンポーネントを作成します。
ファイル構成
src/
├── components/
│ ├── ButtonComponent.tsx
├── test/
│ ├── setup.ts
├── vite.config.ts
ButtonComponent.tsx
のコード
import React from 'react';
import { Button } from '@mantine/core';
interface ButtonComponentProps {
label: string;
onClick: () => void;
}
const ButtonComponent: React.FC<ButtonComponentProps> = ({ label, onClick }) => {
return (
<Button onClick={onClick} data-testid="mantine-button">
{label}
</Button>
);
};
export default ButtonComponent;
3. テストの準備
テストセットアップファイルの作成
setup.ts
ファイルを作成し、テストに必要な設定を記述します。
setup.ts
のコード
import '@testing-library/jest-dom';
// Happy DOM を使用する際に必要な設定
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
vite.config.ts
の設定
vite.config.ts
で Happy DOM を使用するように設定します。
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'happy-dom', // テスト環境を happy-dom に設定
globals: true, // describe, it, expect などをグローバルで使用可能にする
setupFiles: './src/test/setup.ts', // テストセットアップファイルを指定
},
});
4. テストコードの作成
ButtonComponent
をテストするコードを作成します。
ファイル構成
src/
├── components/
│ ├── __tests__/
│ │ ├── ButtonComponent.test.tsx
ButtonComponent.test.tsx
のコード
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MantineProvider } from '@mantine/core';
import ButtonComponent from '../ButtonComponent';
describe('ButtonComponent', () => {
test('renders with the correct label', () => {
render(
<MantineProvider>
<ButtonComponent label="Click Me" onClick={() => {}} />
</MantineProvider>
);
const buttonElement = screen.getByTestId('mantine-button');
expect(buttonElement).toBeInTheDocument();
expect(buttonElement).toHaveTextContent('Click Me');
});
test('calls onClick handler when clicked', async () => {
const handleClick = vi.fn();
render(
<MantineProvider>
<ButtonComponent label="Click Me" onClick={handleClick} />
</MantineProvider>
);
const buttonElement = screen.getByTestId('mantine-button');
await userEvent.click(buttonElement);
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
5. テストの実行
テストが正常に動作することを確認します。
コマンド
npm run test
テスト結果
以下のような出力が表示されれば成功です:
PASS src/components/__tests__/ButtonComponent.test.tsx
ButtonComponent
✓ renders with the correct label (x ms)
✓ calls onClick handler when clicked (x ms)
6. 補足
Happy DOM と jsdom の違い
-
Happy DOM
:- 高速で軽量。
- 基本的な DOM API のサポート。
- シンプルなテストに適している。
-
jsdom
:- DOM API のサポートが充実。
- より複雑なブラウザシナリオに対応。
選択のポイント
複雑なブラウザ依存機能(例: getBoundingClientRect
)が必要ない場合、Happy DOM
は十分な選択肢です。
以上で、Vitest
と Happy DOM
を使った React コンポーネントのテスト環境構築とテストの実行手順が完了です!