はじめに
jestのマッチャ―には拡張マッチャ―というものがあることを知り、こちらもまとめることにしました。
拡張マッチャ―とは
jest-domが提供する拡張マッチャーは標準のマッチャーに追加して、DOM要素の状態や属性を直感的に検証するために使用されるものです。DOM要素の状態・属性・コンテンツに特化した 拡張マッチャーが提供されております。
インストール方法
下記をインストールすることで使用可能
npm install --save-dev @testing-library/jest-dom
jest-domはjestの追加機能のため、単独で動作することはできません。なので下記のjestもインストールしましょう。
npm install --save-dev jest
Typescriptを使用している場合は、tsでも使用できるように下記もインストール
npm install --save-dev @types/jest
セットアップ方法
プロジェクトのルートディレクトリに jest.setup.tsというファイルを作成し、以下の内容を追加します。(TypeScriptを使用しない場合はjest.setup.jsで作成)
import '@testing-library/jest-dom';
プロジェクトのルートディレクトリにjest.config.jsというファイルを作成し、先ほど作成したセットアップファイルを読み込むように設定します。
module.exports = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};
tsconfig.app.json内の"compilerOptions"の中に下記を追記
"types": ["jest", "@testing-library/jest-dom"],
TypeScriptは型チェックを行うので、expect()やtest()などのJestのグローバル関数を知らないとエラーになります。同様に、toBeInTheDocument()など@testing-library/jest-domの拡張マッチャーも型定義がないとエラーになります。
これで、テストファイル内で @testing-library/jest-dom のマッチャーが使用可能になります。(jest.setup.jsに設定しているので全テストファイルでimportなどせずに使用可能)
使用例
import { render, screen } from '@testing-library/react';
import React from 'react';
// サンプルコンポーネント
const MyComponent = () => (
<form>
<button type="submit">送信</button>
<input type="text" aria-label="名前" value="山田太郎" required />
<input type="checkbox" aria-label="同意" checked />
<div className="error">エラーが発生しました</div>
<ul>
<li>リンゴ</li>
<li>バナナ</li>
</ul>
</form>
);
test('@testing-library/jest-dom 拡張マッチャー使用例', () => {
render(<MyComponent />);
// ==========================
// 1. 要素の存在・状態
// ==========================
const button = screen.getByText('送信');
expect(button).toBeInTheDocument(); // DOM に存在するか
expect(button).toBeEnabled(); // 無効化されていないか
expect(button).not.toBeDisabled(); // 無効化されていないことの別表現
const inputName = screen.getByLabelText('名前');
expect(inputName).toBeRequired(); // 必須入力かどうか
expect(inputName).toBeValid(); // 有効な状態かどうか
expect(inputName).not.toBeInvalid();// 無効でないことの確認
const checkbox = screen.getByLabelText('同意');
expect(checkbox).toBeChecked(); // チェックされているか
expect(checkbox).not.toBePartiallyChecked(); // 部分チェックされていないか
// ==========================
// 2. 属性・スタイル
// ==========================
const errorDiv = screen.getByText('エラーが発生しました');
expect(errorDiv).toHaveClass('error'); // クラス名があるか
expect(errorDiv).toHaveAttribute('class', 'error'); // 属性と値を確認
expect(errorDiv).toHaveStyle('color: red'); // スタイルを確認(例:CSSが適用されている場合)
// ==========================
// 3. コンテンツ・値
// ==========================
expect(inputName).toHaveValue('山田太郎'); // input の値
expect(button).toHaveTextContent('送信'); // 要素内のテキスト
expect(screen.getByRole('list')).toContainElement(screen.getByText('リンゴ')); // 子要素を含むか
// ==========================
// 4. HTML 構造
// ==========================
const list = screen.getByRole('list');
expect(list).toContainHTML('<li>リンゴ</li>'); // 部分的に HTML を含むか
// ==========================
// 5. アクセシビリティ / フォーカス
// ==========================
// フォーカスやアクセシブルネームはフォームやボタンでチェック可能
expect(button).toHaveFocus(); // ボタンがフォーカスされているか
expect(button).toHaveAccessibleName('送信'); // アクセシブルネーム
});
おわりに
通常のjestとは違いjest-domは画面に出るHTMLをテストするライブラリになっており、jestとの違いの理解が深まりました。まだ学びたてなのでこれからも自分なりにまとめて学びやすいようにしたいと考えております。
ISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!