📃

Bunを使用したReactコンポーネントのスナップショットテスト

2024/08/15に公開

前提条件

  • Next.jsプロジェクトが設定されている(React向けに書いたため)
  • Bunがインストールされている

1. happy-domの導入

まずDOMシミュレーションのためにhappy-domを導入します。

bun add -d @happy-dom/global-registrator

次にhappy-domを設定するファイルを作成します。

happydom.ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";
GlobalRegistrator.register();

bunfig.tomlをなければ作成、あれば編集します。

bunfig.toml
[test]
preload = "./happydom.ts"

2. テスト対象のコンポーネント

例としてシンプルなボタンコンポーネントを以下のように作成しました。

Button.tsx
import React from 'react'

interface ButtonProps {
  onClick: () => void
  text: string
}

const Button: React.FC<ButtonProps> = ({ onClick, text }) => {
  return <button onClick={onClick}>{text}</button>
}

export default Button

3. スナップショットテストの実装

作成したボタンコンポーネントをテストするために以下のファイルを作成します。

Button.test.tsx
import { test, expect } from 'bun:test'
import { createElement } from 'react'
import { renderToString } from 'react-dom/server'
import Button from './Button'

test('Button renders correctly', () => {
  const button = createElement(Button, { onClick: () => {}, text: 'Click me' })
  const renderedString = renderToString(button)
  expect(renderedString).toMatchSnapshot()
})

4. テストの実行

以下のコマンドでテストを実行します。

bun test

もし前回実行時と異なる結果が帰ってきた場合、以下のようにエラーが発生します。

4 | import { Button } from '.'
5 | 
6 | test('button renders', () => {
7 |   const button = createElement(Button, { onClick: () => {}, text: 'Click me' })
8 |   const renderedString = renderToString(button)
9 |   expect(renderedString).toMatchSnapshot()
                             ^
error: expect(received).toMatchSnapshot(expected)

Expected: "<button>Click me</button>"
Received: "<button class="p-1">Click me</button>"

5. スナップショットの更新

コンポーネントに意図した変更を加えた場合、以下のようにコマンドを実行することでスナップショットを更新できます。

bun test --update-snapshots

感想

単純なHTML構造だけを対象にテストを書くなら今回の記事のような形で問題ないかと思いますが、ユーザーインタラクションなテストを書くならReact Testing Libraryを使うことになるのかなと思います。

想像していた以上にBunを使用したテスト、簡単に書くことができてしかも爆速なので個人開発では率先して使っていきたいなーという気持ちです。

参考

https://bun.sh/docs/test/dom

テクシア テックブログ

Discussion