5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jest & React Testing Libraryに入門してみた

Posted at

はじめに

Jest React Testing Libraryについて理解を深めるため記事にしました。

理解するためのアプローチ

以下の流れで進めることにしました。

  1. JestとReact Testing Library がそもそも何なのかを理解する
  2. JestとReact Testing Libraryの基本的なテストコードの書き方を理解する
  3. 自分で作ったプロジェクトにテストを組み込んで見る

1. Jest & React Testing Library の基本を知る

Jest と Testing Library が何をするものなのか、大まかに理解する。

Jestとは

JavaScript テスティングフレームワーク
関数やロジックを対象としてテストすると理解

Jest はあらゆる JavaScript のコードベースの正しさを保証するために設計された JavaScript テスティングフレームワークです。親しみやすく、豊富な機能を持つAPIによって簡単にテストを書くことができ、さらには素早く結果を得ることができます。

React Testing Libraryとは

Reactコンポーネントのテストを行うためのライブラリ。
「ユーザーの視点でテストを書く」 ためのツールを提供

ユーザーがボタンを押したり、画面に入力した際正しく動くかどうかなどユーザーが行う操作に対してテストすると理解

2. 基本的なテストの書き方を覚える

Jest

公式のチュートリアルでは以下の順番で説明されていました。

  1. Matcher
  2. 非同期コードのテスト
  3. セットアップと破棄
  4. モック関数
  5. Jestプラットフォーム

1.Matcher

sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;
sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

expect()にテストしたい対象を指定(sum関数)
toBe()に期待値を指定

値が厳密に等しいかどうかをテストしてくれる。

2.非同期コードのテスト

・ Async/Await
・ .resolves / .rejects

async と awaitをテストで使用できます。 非同期テストを書くには、 testに渡す関数の前にasync キーワードを記述するだけです。 例えば、同じfetchData シナリオは次のようにテストできます:

テストコードでもasync/awaitの使用ができると理解

expect宣言で.resolves マッチャを使うこともでき、Jestはそのpromiseが解決されるまで待機します。 promiseがrejectされた場合は、テストは自動的に失敗します。

promiseがrejectされることを期待するケースでは.rejects マッチャを使用してください。 .resolvesマッチャと似た動作をします。 promiseが成功した場合は、テストは自動的に失敗します。

test('the data is peanut butter', async () => {
  await expect(fetchData()).resolves.toBe('peanut butter');
});

test('the fetch fails with an error', async () => {
  await expect(fetchData()).rejects.toMatch('error');
});

テスト対象expect(fetchData())の処理が完了されることを確認できるのが.resolvesマッチャ
テスト対象expect(fetchData())の処理が完了されないことを確認できるのが.rejectsマッチャ

3.セットアップと破棄

繰り返しのセットアップ beforeEachとafterEach

多くのテストで繰り返し行う必要がある場合は、beforeEach と afterEach フックを使用します。

各テストで同じ処理を何度も実行する必要がある場合に使用できると理解

beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

city database has Vienna、city database has San Juanそれぞれのテスト実行前にinitializeCityDatabase();を実行
テスト実行後はclearCityDatabase();が実行される

4.モック関数

const mock = jest.fn();でモックを作れる。
テスト対象で実際に動かしたくないときに使用。

5.Jestプラットフォーム

Jestの特定の機能をパッケージ化して便利にしたもの

React Testing Library

こちらの記事とドキュメントを参考にしました。

1.レンダリング

render関数でテストしたいコンポーネントをレンダリング

import App from "../App";
import React from "react";
import { render, screen } from "@testing-library/react";

describe("Title Test", () => {
  it("test1", () => {
    render(<App />);
		screen.debug();
  });
});

screen.debug()でコンポーネントの中身をコンソール上で表示できる
image.png

2.要素の取得

レンダリングした要素を取得して、テスト対象を特定します。
要素の取得方法は下記の記事を参考にしました。

getByとfindByの違いについて、エラーを通して理解しました

  • getBy*: 要素が見つからないと例外を投げる(存在確認用)
  • queryBy*: 要素が見つからなくてもnullを返す(非存在確認用)
  • findBy*: 非同期で要素を探し、Promiseを返す(非同期表示確認用)

3.自分で作ったプロジェクトにテストを組み込んで見る

テストしたいこと

入力をしないで登録を押すとエラーが表示される

実現するために

expect:登録ボタンを押下
Matcher:画面に表示されたエラー内容が期待値通りになること
で実現できるか考えてみました

import App from "../App";
import React from "react";
import '@testing-library/jest-dom'
import { render, screen, within, waitFor, cleanup} from "@testing-library/react";
import userEvent from "@testing-library/user-event";

afterEach(() => {
	cleanup();
});

describe("RegistDelete Test", () => {
	it("入力をしないで登録を押すとエラーが表示される", async () => {

		render(<App />);

		// 登録ボタン押下
		userEvent.click(await screen.findByTestId("add"));

		expect(await screen.findByTestId("error")).toHaveTextContent("入力されていない項目があります");
	});
});

おわりに

基本的なことをまとめてみました。モック関数などまだまだわからないことばかりなので、今後も学習を進めて適切なテストコードをかけるようになりたいです。

参考

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?