🚀

Next.js + Chakra UIプロジェクトにJestを導入してGitHub Actionsでユニットテストをする

2021/07/02に公開

はじめに

※この記事は下記記事の延長です。下記記事を読まなくても問題ないように書いていますが、ご興味ありましたらご一読ください。
https://zenn.dev/a_da_chi/articles/181ea4ccc39580#スナップショットテスト導入

ReactでユニットテストといえばJestですよね。
今回はNext.js+Chakra UIプロジェクトにJestを導入してGitHub Actionsでユニットテストをするまでの手順を書いていきたい思います。

前提

  • Next.jsでsrcディレクトリ配下にアプリケーションコードを配置していること

導入手順

  1. 必要なパッケージをインストール
  2. npm scriptsをpackage.jsonに追加
  3. 設定ファイルを追加
  4. React Testing LibraryのcustomRenderを定義
  5. ユニットテストやスナップショットテストを書く
  6. GitHub Actionsの設定

必要なパッケージをインストール

yarn add --dev jest @types/jest babel-jest @testing-library/react

@testing-library/reactはReactコンポーネントをテストする場合に必要です。

npm scriptsをpackage.jsonに追加

"scripts": {
  "test": "jest"
}

これでyarn testでJestによるテスト実行が可能になります。

設定ファイルを追加

jest.config.js
module.exports = {
  /** @link https://stackoverflow.com/questions/50863312/jest-gives-cannot-find-module-when-importing-components-with-absolute-paths */
  moduleDirectories: ['node_modules', '<rootDir>/'],
  roots: ['<rootDir>/src/'],
  testEnvironment: 'jsdom',
  testPathIgnorePatterns: [
    '/node_modules/',
    '<rootDir>/src/__tests__/utils.tsx',
  ],
  transform: {
    '^.+\\.(ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
  },
}

とりあえず最低限の設定です。個人的にハマった設定についてはコメントに参考リンクを書いているので参考にしてみてください。

React Testing LibraryのcustomRenderを定義

src/__tests__/utils.tsx
import { ChakraProvider } from '@chakra-ui/react'
import { render } from '@testing-library/react'
import React from 'react'
import theme from 'src/theme'

const AllTheProviders = ({ children }: { children: JSX.Element }) => {
 return <ChakraProvider>{children}</ChakraProvider>
}

const customRender = (ui: JSX.Element, options?: any) =>
 render(ui, { wrapper: AllTheProviders, ...options })

export * from '@testing-library/react'
export { customRender as render }

styled-componentsでThemeProviderを使用している場合などに必要です。今回はChakra UIを使用している場合の例です。

ユニットテストやスナップショットテストを書く

ここまでで設定は完了なので早速テストを書いてみましょう。

まずは関数のユニットテストを書いてみましょう。以下のような関数があったとします。

src/lib/math.ts
export const add = (a: number, b:number) => a + b

それに対するテストは以下です。

src/lib/math.test.ts
import { add } from './math'

test('add', () => {
  expect(add(1, 1)).toEqual(2)
})

次にReactコンポーネントのスナップショットテストを書いてみましょう。以下のようなページコンポーネントがあったとします。

src/pages/index.tsx
import React from 'react'

export default function HomePage() {
  return <h1>Hello Jest!</h1>
}

それに対するテストは以下です。

src/__tests__/pages/index.test.tsx
import React from 'react'
import HomePage from 'src/pages'
import { render } from '../utils'

test('ホームページ', () => {
  const { container } = render(<HomePage />)
  expect(container).toMatchSnapshot()
})

この状態でターミナルで以下のコマンドを入力して、テストを実行します。

yarn test

するとJestによるテストが実行されます。
今回はスナップショットテストも書いたので、src/__tests__/pages/__snapshots__/index.test.tsx.snapが自動生成されます。
もしsrc/pages/index.tsxの出力結果に差異が生じた場合はテストが失敗しますが、それが意図した差異であればjest --updateSnapshotでスナップショットを更新してください。

GitHub Actionsの設定

ここまででローカル環境ではテストを実行するところまで完了したので、GitHub Actionsでも実行できるようにしましょう。

以下の設定ファイルを追加してください。

.github/workflows/main.yml
name: Main

on: pull_request

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: 14.x
      - uses: actions/cache@v2
        with:
          path: ~/.cache/yarn
          key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
          restore-keys: ${{ runner.os }}-yarn-
      - name: Install dependencies
        run: yarn install --frozen-lockfile --prefer-offline
      - name: Run test
        run: yarn test

この状態でGitHubでPRを作成するとJestが実行されると思います。

おわりに

いかがでしたか。
これでNext.js+Chakra UIプロジェクトにJestを導入してGitHub Actionsでユニットテストをすることができました。
フロントエンド開発でJestは必須だと思うのでぜひ導入してみてください。
それではよいNext.jsライフを!

Discussion