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拡張を使って、テストしたいコンポーネントを調査するのと楽。
これでフロントエンド側のテストも書いていけるようになった。