Open14

テスト入門 〜Jest&testing-libraryの巻〜

ピン留めされたアイテム
ふくえもんふくえもん

手順まとめ

1. 必要なパッケージのインストール

テスト用のライブラリの他に、jestのコンパイルのためのパッケージとAPIの型定義ファイルもまとめてinstall

npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event ts-jest @types/jest

2. jestの設定

jest.config.js

const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './'
})

/** @type {import('jest').Config} */
const config = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], //setup.jsを読み込むように(別途用意)
  preset: 'ts-jest', // TypeScriptのコンパイル用のパッケージ
  testEnvironment: 'jest-environment-jsdom',

  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  }
}

module.exports = createJestConfig(config)

jest.setup.js

import '@testing-library/jest-dom'

3. tsconfigの修正

typesを追加

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
+    "types": ["node", "jest", "@testing-library/jest-dom"],
    "allowJs": true,
    "skipLibCheck": true,

4. babelの設定

test実行時にjsxファイルをコンパイルできないみたいなエラーが出るため、babelの設定を行う(理解が曖昧)
baberのpresetをインストール

npm i @babel/preset-react @babel/preset-typescript

設定ファイルを追加
.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"]
}

5. eslintのplugin追加

npm i eslint-plugin-jest-dom eslint-plugin-testing-library

.eslintrc.jsに設定を追加

module.exports = {
  root: true,
  extends: [
    'plugin:@typescript-eslint/recommended',
    'next/core-web-vitals',
    'prettier',
    'plugin:tailwindcss/recommended',
    'plugin:storybook/recommended'
  ],
+  plugins: ['unused-imports', 'testing-library', 'jest-dom'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json'
ふくえもんふくえもん

奮闘記

Jestとtesting-libraryを導入します
https://nextjs.org/docs/pages/building-your-application/optimizing/testing

ふくえもんふくえもん

インストール

npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
ふくえもんふくえもん

設定ファイルの作成

jest.config.mjs

import nextJest from 'next/jest.js'
 
const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})
 
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
 
  testEnvironment: 'jest-environment-jsdom',
}
 
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)
copilot先生

このコードは、Next.jsアプリケーションのJestテストを実行するためのJest設定ファイルです。以下のような機能が含まれています。

next/jest.jsをインポートして、Next.jsアプリケーションのJest設定を作成します。
dirオプションを使用して、テスト環境でnext.config.jsと.envファイルを読み込むために、Next.jsアプリケーションのパスを提供します。
jest-environment-jsdomを使用して、Jestテストの実行に必要な環境を設定します。
createJestConfig関数をエクスポートして、Jest設定を返します。
このコードは、Jestを使用してNext.jsアプリケーションのテストを実行するための基本的な設定を提供しています

ふくえもんふくえもん

ts-jestの導入
jestのコンパイルのためのパッケージとAPIの型定義ファイルをinstall

npm i ts-jest @types/jest

これがないとTypeScriptで書いた時に怒られる

ふくえもんふくえもん

jest.config.jsを編集する

const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './'
})

/** @type {import('jest').Config} */
const config = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
}

module.exports = createJestConfig(config)

ts-jestを読み込んで、setupファイルも別で読み込むようにする

ふくえもんふくえもん

jest.setup.jsを追加

import '@testing-library/jest-dom'

参考にしてたものでは、以下のようになってけど、今のVerではextend-expectの部分はいらないみたい

import '@testing-library/jest-dom/extend-expect'
ふくえもんふくえもん

上記のextend-expectだと以下のように、エラーになる

 FAIL  src/app/_components/Common/BottomNavbar/__tests__/BottomNavbar.test.tsx
  ● Test suite failed to run

    Cannot find module '@testing-library/jest-dom/extend-expect' from 'jest.setup.js'



      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at Object.<anonymous> (jest.setup.js:5:1)
ふくえもんふくえもん

test時にbabel関連のエラーが発生する

SyntaxError: ... Support for the experimental syntax 'jsx' isn't currently enabled (8:42):

...
    Add @babel/preset-react (https://github.com/babel/babel/tree/main/packages/babel-preset-react) to the 'presets' section of your Babel config to enable transformation.
    If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-jsx) to the 'plugins' section to enable parsing.

      at constructor (node_modules/@babel/parser/src/parse-error.ts:81:19)
    prList [as parseArrayLike] (node_modules/@babel/parser/src/parser/expression.ts:2493:26)
      at Parser.parseArrayLike [as parseExprAtom] (node_modules/@babel/parser/src/parser/expression.ts:1182:21)
      at Parser.parseExprAtom [as parseExprSubscripts] (node_modules/@babel/parser/src/parser/expression.ts:710:23)
...

babelの設定を追加してあげる必要があるみたい?
ここら辺の解釈が曖昧なので、時間があれば深く学びたい

ふくえもんふくえもん

baberのpresetをインストール

npm i @babel/preset-react @babel/preset-typescript

設定ファイルを追加
.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"]
}

ふくえもんふくえもん

最後にnext.jsのエイリアスをマッピングできるようにjestの設定する
jest.config.js

const config = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',

+  moduleNameMapper: {
+    '^@/(.*)$': '<rootDir>/src/$1'
+  }
}
ふくえもんふくえもん

Babelファイルは必要ない?

.babelrcファイルがルートディレクトリではなく、srcディレクトリ内に配置していたので、ルートディレクトリに移動した。
すると、以下のエラーが発生した

構文エラー: "next/font" は SWC を必要としますが、カスタム babel config が存在するため Babel が使用されています。
もっと読む: https://nextjs.org/docs/messages/babel-font-loader-conflict

ふくえもんふくえもん

そのため、babelファイルを削除して、もう一度Testを実行してみることに

実行できた
そもそもbabelファイルは必要なかった?