Jest

単体テストを行うテスティングライブラリ「Jest」。

■環境構築

Next.js Testing

Next.js + Jest

Next.js(TypeScript)にJestを設定する方法

Next.js 12でJestの設定がかなり楽になった

公式docを参考に、必要なライブラリをインストール

yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

jest.config.jsをルートディレクトリに新規作成し、以下をコピペ。

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: './',
})

// Add any custom config to be passed to Jest
const customJestConfig = {
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
  moduleDirectories: ['node_modules', '<rootDir>/'],
  testEnvironment: 'jest-environment-jsdom',
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)

tsconfig.jsonに、もし記載がなかったら、以下を追記。

est.config.jsをルートディレクトリに新規作成し、以下をコピペ。

{
  "compilerOptions": {
    (中略)
    "baseUrl": ".",
    "paths": {
      "@/components/*": ["components/*"], //これ
      "@/pages/*": ["pages/*"] //これ
    },
  },

ルートディレクトリにjest.setup.jsを新規作成し、以下をコピペ。

// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`

// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'

package.jsonに、無ければ、以下を追記。

{
  (中略)
  "scripts": {
  (中略)
    "test": "jest --watchAll", //これ
    "test:ci": "jest --ci" //これ
  },

componentsディレクトリに、テスト用のディレクトリを作成

cd components
mkdir __test__

サンプル用。

テストされる側のコード。

components > Sample.tsx

export const Sample = () => {
  return (
    <>
      <h1>Nextjs+Jestのサンプルサプリ</h1>
      <button>設定がすごく楽になりました。</button>
    </>
  );
};

テスト用実行用のコード。

components > test > Sample.test.tsx

import { Sample } from "@/components/Sample";
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom';

describe('Sample', () => {
  it('renders a heading', () => {
    render(<Sample />)

    const appTextElement = screen.getByRole('button', {name: '設定がすごく楽になりました。'})

    expect(appTextElement).toBeInTheDocument()
  })
})

yarn コマンドでテスト実行。

yarn test

■代表的コマンド

(参考サイト)ユニットテストツール「Jest」の使い方

React testing-library で getByText, getByRole, getAllByRole を比較する

コード例。テストされる側。

function sum(a, b) {
    return a + b
}
module.exports = sum

テストする側。

const sum = require('./sum')

test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3)
})
  • テスト対象ファイルを読み込み
  • test関数

    第1引数にテストの概要を記述

    第2引数にテストを記述

  • expect関数

    引数にテスト対象の処理を記述

    マッチャー( toBe toEqual など)で期待する動作を検証

  • 「test関数」と「it関数」

    ここではtest関数を利用しましたが、it関数でも同じ動作をします

  • 「describe関数」でテスト対象をカテゴライズ

    ここでは利用しませんでしたが、describe関数を利用すると複数のテストをグルーピングできます。テストのカテゴライズができるので、テストの管理に役立ちます。

coverageオプション を利用するとテストカバレッジを確認できます。

yarn test --coverage

coverageオプション を利用した場合、テストを実行すると coverageフォルダ が生成されます。

coverage/lcov-report/index.html をブラウザで開くと詳しいカバレッジ情報を確認できます。

watch, watchAll

yarn test 実行テストファイル名 --watchAll

利用頻度の高いMatcherを紹介します。

it('matchers', () => {
    // 等しい
    expect(1 + 5).toBe(6)

    // notで「~でない」の判定ができます。
    expect(1 + 5).not.toBe(7)

    // toBeは厳密な等価性を判定するので、オブジェクトの場合はtoEqualを利用します。
    expect({ a: 100 }).toEqual({ a: 100 })

    // 大きい
    expect(4).toBeGreaterThan(3)
    expect(4).toBeGreaterThanOrEqual(4)

    // 小さい
    expect(4).toBeLessThan(5)
    expect(4).toBeLessThanOrEqual(4)

    // null, true, false
    expect(null).toBeNull()
    expect(true).toBeTruthy()
    expect(false).toBeFalsy()

    // 文字列
    expect('abcdefg').toMatch(/bc/)
    expect('abcdefg').not.toMatch(/bd/)

    // 配列
    expect([1, 2, 3]).toContain(2)

    // 例外
    const xxx = () => {
        throw new Error('error message xxx');
    }
    expect(xxx).toThrow('error message xxx');
    expect(xxx).toThrow(/.*xxx$/);
})

下記ページでより詳しい使い方を確認できます。

代表的なものだけ確認

https://jestjs.io/docs/en/using-matchers

全てのMatcherを確認

https://jestjs.io/docs/en/expect