EY-Office ブログ

JestまたはVitestとReact Testing LibraryでReactテスト環境の構築

前回のブログにReact Testing Libraryを使ったコンポーネントのUIテストを取り上げましたが、そこに至る前にReactのUIテスト環境作りで少し悩んだので、その事を書きます。

vite-vitest_react DeepAIが生成した画像です

create-react-app の開発が止まってしまった・・・

2023年以前はReactアプリを作るには Create React Appを使うのが普通だったと思います、しかし2023年になってからCreate React App Gone From React.dev, What happens to it now?Goodbye create-react-app, Create React App is dead! What are the alternatives?のようなイシューや記事が書かれるようになってきました。Create React AppのGitHubを見ると2022年9月で更新が止まっています!

それでは現在Reactアプリを作るには、何を使ったら良いのでしょうか? 上にあげた記事には以下が薦められています。

  1. Next.jsRemix等のReact用フレームワークを使う
  2. Vite等の次世代フロントエンド・ツールを使う

SSR(Server Side Rendering)やVercel等のCDN・Edgeを使う事が予定されているのであれば、Next.js等のフレームワークでしょうか。またバックエンドも含む場合はRemixでしょうか。

単純なReactアプリであればViteでしょうか。以前書いたViteのブログ → Viteは爆速だと聞いて試したら爆速だった(Next Generation Frontend Tooling)

create-react-app で作ったプロジェクトではテストが直ぐ書けました

create-react-appの良い点は、最初からJest + React Testing Libraryのテスト環境が入っているとこです、前回のブログに書いたUIテストはそのまま動きます。

初心者がテストを書くにには技術的・心理的な障害があると思いますが、インストールが面倒で離脱してしまう人もいるかと思います。

ところが、Next.js、Remix、Viteにはデフォルトのテスト環境はありません。🥺

Vite環境でJestを動かす

Vite環境でもJestを動かす事ができます。すでにcreate-react-app環境上でJestで書かれた大量のテストがある場合も安心(?)してViteに移行できます。

インストール手順等

  • インストール
npm install --save-dev jest ts-jest jsdom jest-environment-jsdom
npm install --save-dev @testing-library/react @testing-library/jest-dom @types/jest
  • Jest設定ファイル ./jest.config.js

export default {
  testEnvironment: "jsdom",
  transform: {
    "^.+\\.tsx?$": "ts-jest"
  },
  setupFilesAfterEnv: ["./src/setupTests.ts"],
}

本当は TypeScript ./jest.config.ts にしたいのですが、現状ではエラーになります(Jestのバージョンアップで対応される予定らしいです)。

  • テスト設定ファイル ./src/setupTests.ts
import '@testing-library/jest-dom/extend-expect';
  • tsconfig.jsonの修正

TS151001ワーニングが出るので対応

{
  "compilerOptions": {
    ・・・
    "esModuleInterop": true,  // ← 追加
    ・・・
   },
  ・・・
}

将来的にはViteにはVitestでしょうか

実はViteにはVitestというテストフレームワークがあります。ただし現時点でバージョン0.3xです!
やはりネット上にはVitest is production-ready 👀” [AskJS]How many of you are already using vitest in production, and what are your experiences?のように、製品につかってもだいじょうぶ?と思っている人がいるようです(私も少し不安があります😁)。

他方、Vitestを使った記事はネット上にたくさんあります。

Vitestにはいろいろな特徴がありますが、ホームページにもJest Compatible と書かれています。先週のブログのテストコードは2か所変更するだけで動きました!
そして、高速です。

import { render, screen, fireEvent } from '@testing-library/react';
import { vi } from 'vitest';  // ← 変更 ①
import App from './App';

describe('App', () => {
  test('チョキ ボタンを押すと対戦結果が表示される', () => {
    global.Math.random = vi.fn(() => 0.9);  // ← 変更 ②
    render(<App/>);

    fireEvent.click(screen.getByRole("button", {name: "チョキ"}));

    const cells = screen.queryAllByRole("cell").map(e => e.textContent);
    expect(cells.slice(1)).toEqual(['チョキ', 'パー', '勝ち'])
  });
});

変更点は、jestMockオブジェクトがvi(vitestの略でしょうか)にかわっただけです!

インストール手順等

インストールや設定ファイル設定は簡単です。

  • インストール
npm install --save-dev vitest jsdom @testing-library/react @testing-library/jest-dom
  • Vitest設定ファイル vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'jsdom',
    setupFiles: ['./src/setupTests.ts'],
    globals: true
  }
});
  • テスト設定ファイル ./src/setupTests.ts
import matchers from "@testing-library/jest-dom/matchers";
import { cleanup } from "@testing-library/react";
import { afterEach, expect } from "vitest";

// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers);

// runs a cleanup after each test case (e.g. clearing jsdom)
afterEach(() => {
  cleanup();
});

まとめ

現在Reactの開発環境は、決定打がない状況にあります。Next.jsRemixのようなフレームワークを使う予定があれば、それらを採用するのが良いと思います。
それらのフレームワークを使う予定がないならViteが良さそうです。

テスティング環境については、すでにJestのテストコードがあればViteの上でJestを動かすのが良さそうです。
新規プロジェクトならVitestでしょうか。Jestに近いコードが高速に動くのが魅力的です。

- about -

EY-Office代表取締役
・プログラマー
吉田裕美の
開発者向けブログ