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

SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92

クロスオリジン分離対応を実施

react-hook-formとReact Datepickerを組み合わせる

Hook FormのControllerを使う

Next.jsで生成したサイトで特定のページのみnoindexを設定する

タグに紐づく記事一覧ページはnoindexにした

Next.jsでAdsenseタグを埋め込んだら Only one AdSense head tag supported per page エラーが発生

Only one AdSense head tag supported per page. The second tag is ignored.