React Testing Libraryを使ってNext.jsアプリのテストを書く

React Testing Libraryを使ってNext.jsアプリのテストを書く
公開日時

フロントエンドにNext.js、バックエンドにFastifyを使ってWebアプリを開発した際に、バックエンド側はAPIのrequestテストを書いていたがフロントエンド側のテストが手つかずになっていた。

とはいえフロントエンド側の比重が増えているので必要最低限のテストは書いておきたいと思い、React Testing Libraryでコンポーネントのテストを書くことにした。

jest設定

ts-jestを使ってTypescriptでテストを書こうとした際に↓のエラーが発生した。

SyntaxError: Unexpected token <

tsconfigのcompilerOptions.jsxをpreserveからreactに変更すればエラーが解消されるのだが、tsconfig.jsonを直接書き換えてもnext.js起動時にpreserveに書き換わってしまうのでテスト専用のtsconfigを追加した。

cp tsconfig.json tsconfig.test.json

vi tsconfig.test.json

{
  "compilerOptions": {
    "jsx": "react",
    // ...
  }
}

[[jest.config.js]]に↓を追加すればテスト用のtsconfigを参照してくれる。

module.exports = {
  preset: 'ts-jest'
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.test.json',
    },
  }
}

コンポーネントのテスト

↓のようにして詳細なDOMのチェックはせずに、指定のDOMが存在することのみチェックしている。

// test/pages/HomePage.test.tsx
import '@testing-library/jest-dom/extend-expect'

import { render } from '@testing-library/react'
import React from 'react'

import HomePage from '@/pages/index'

describe(`HomePage`, () => {
  it('matches document', () => {
    const { getByTestId } = render(
      <HomePage />
    )
    expect(getByTestId('feature-post')).toBeInTheDocument()
  })
})

ただ、テストを書いた後に改めてTesting Libraryのドキュメントを読み直して、getByTestIdは推奨されていないことに気づいた。

The more your tests resemble the way your software is used, the more confidence they can give you.

Which query should I use? | Testing Library」にあるようにgetByRoleを使うようにするとテストを書くことでアクセシビリティに優れたWebアプリを作っていけるとのことなので、可能な限りgetByRoleを使うように変えていこう。

getByRoleの指定方法については↓のChrome拡張を使って、テストしたいコンポーネントを調査するのと楽。

これでフロントエンド側のテストも書いていけるようになった。

参考


Related #next.js

Next.jsのPreview Mode時はAnalyticsを無効化する

cookieの__next_preview_dataキーで判定

PWAアプリにクイックショートカットを追加する

manifest.jsonにshortcutsを追加

Next.js 10.0.1 + React 17.0の環境でTypeError: Object(...) is not a functionエラーが発生

一つ前のReact 16.13に下げてみたらエラーが解消された

Next.jsプロジェクトにTypescriptを導入する

チュートリアルが充実してる

Next.js + typescriptでpathsのエイリアスがModule not foundになる

next.config.jsに追記する必要があった