グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



プロダクトにReact Testing Library(RTL)を導入してみてハマったこと

みなさんテスト書いてますか。

恥ずかしながら、筆者が開発中のプロダクトでは、現状ではお世辞にもテストがあるとは言えない状況です。

今回は開発中プロダクトにReact Testing Library(RTL)を導入してハマったことについてご紹介したいと思います。

React Testing Library(RTL)の導入

テストランナーにはjestを使用するのでjestをまずインストールしていきます。

続いて React Testing Library(RTL) をインストールします。

jestの設定ファイル jest.config.ts を追加します。

jest.config.ts
 package.json にテスト用のnpm scriptsを追加します。

package.json

これで npm run test テストを実行できるようになります。

Vite編

Viteで設定したaliasがjestで読み込まれない

Error

原因

Viteで  import { Component } from @/components/…  のようにimport出来るようにaliasを設定している。
Viteでaliasを設定していて、  @/path/to/module  のように絶対パスでimport構文を定義していました。 jestはVite経由で実行されないので、jestがaliasを解釈できずにエラーとなっているようです。

※例
vite.config.ts

対策

aliasの設定をjestでパスを解決する仕組み moduleNameMapper で設定します。

jest.config.js

import.meta 使用箇所でエラー

Error

原因

 import.meta  を使用している。
 import.meta はECMA Script Module (ESM) 、もっというと  es2020  以降でしか動作しないようで、 ts-jest で対象ファイルをCommonJS形式にコンパイルしてしまうため、 import.meta を解釈できずにエラーになっていると思われます。

対策

調べた限り解決方法は2パターン

  1. テスト実行環境をESM対応する
  2.  import.meta  process.env  に書き換える
 1.  を試した結果、styled-componentsがESM対応出来ておらず、 styled.span is a not function となってしまいstyled-components使用コンポーネントでエラーになり、他にもESM対応で悉くエラーになりつらみ。

また、 1.  の対応をしても  import.meta  のところは結局改善せず、 2. の対応またはmock対応を行わないといけないので一旦ESM対応は断念しました。

そのため、 2. の方法で、 import.meta  使用箇所を  process.env  に置き換えることで対応しました。

vite.config.ts

RTLがReactコンポーネントを解釈できない

Error

原因

tsconfig.json の  esModuleInterop  false になっている。

対策

tsconfig.json

esModuleInteropとは何か

default exportを使用しているライブラリのCommonJS形式へのコードコンパイル時に、importができないため相互運用性を高めるためのオプション。 今回のケースだと、ts-nodeがCommmonJS形式にコンパイルされたdefault exportのReactをimportできないため発生したエラーと思われます。

TODO: Viteのdevサーバだとなんで動くのか

ここは理解不足なのですがjestはCommonJS形式、ViteはESM形式で動作してるから?

Jest編

jestでtest environment関連のエラー

Error

原因

jest v27から  testEnvironment  のデフォルト値が  jsdom  から  node  に変更になった。

対策

jestの設定で  testEnvironment  の値を  jsdom  に設定します。

jest.config.js

RTL編

RTLで toBeInTheDocument is not a function

Error

原因

テストファイルに  import ‘@testing-library/jest-dom’  の記述がない。またはjset-domの設定がされていない。

Usage

Import @testing-library/jest-dom once (for instance in your tests setup file) and you’re good to go:

// In your own jest-setup.js (or any other name) import ‘@testing-library/jest-dom’

// In jest.config.js add (if you haven’t already) setupFilesAfterEnv: [‘/jest-setup.js’]https://github.com/testing-library/jest-dom#usage

対策

一括で設定する場合

jest.config.js
jest.setup.ts

RTLの screen.debug() の出力表示が省略される

原因

デフォルトでは7000文字で丸め込まれる。

対策

環境変数に  DEBUG_PRINT_LIMIT  を追加します。

return component(render) hooksパターンのテストが通らない

汎用的なコンポーネントを再利用するためにreturn component(render) hooksパターンをモーダルなどで活用しています。
例としてはこのようなカスタムフックです。

useModal.tsx
このカスタムフックのテストを書いて実行すると、なぜかテストが通らずえらくハマりました。

useModal.test.tsx
Error

原因

原因については詳細は不明ですが、RTLの  renderHooks  を使って今回のようなコンポーネントを返すhooksをテストするとReactのReconciliationが実行されないようです。

対策

このようなパターンの時は  renderHooks  ではなくReactコンポーネントをそのまま使う。

useModal.test.ts
こうすることでテストが通るようになりました。

番外編

ts-jest から @swc/jest に変更する

 @swc/jest  をインストールします。
jestの設定に  @swc/jest  の設定を追加します。

jest.config.js

速度比較

Before After
Test Suites: 3 passed, 3 total 3 passed, 3 total
Tests: 75 passed, 75 total 75 passed, 75 total
Snapshots: 0 total 0 total
Time: 2.818 s, estimated 3 s 0.966 s, estimated 1 s

おおよそ3倍くらい早くなりました。 体感としても早くなり、とても気持ちがいいです。

さいごに

簡易的ですが、React Testing Library(RTL)を導入してみてハマったことについてお伝えしました。
アサーションやテストのやり方について覚えることが多く中々テストを書けていませんでしたが、徐々にでもテストを拡充していきたいですね。

The following two tabs change content below.

美髭公

ソリューション事業部 システムエンジニア
2013年にアーティスに入社。システムエンジニアとしてアーティスCMSを使用したWebサイトや受託システムの構築・保守に携わる。環境構築が好き。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします