😺

React に Storybook を導入して自動テストする

2023/01/26に公開

React + Storybook

React に Storybook を導入します

まずは、React プロジェクトの作成から。

$ npx create-react-app my-react-auth0-sampleapp

コードの準備ができたら cd コマンドで階層を移動して npm start でアプリケーションを実行します。

$ cd my-react-auth0-sampleapp
$ npm start

React の画面がブラウザで表示されればOKです。

Storybook の導入

続いて、Storybook の設定を進めます。

React プロジェクトのセットアップができたら storybook init コマンドを用いて、
Storybook を使用する準備を進めましょう。
storybook init は、インストールされているフレームワークを認識して、
最適な設定を自動的に施してくれます。

$ npx storybook init

React プロジェクトで storybook init を実行した場合、以下の処理がプロジェクト内のフォルダに自動的に適用されます。

  • .storybook フォルダを作成し、storybook 設定を出力
  • src/stories フォルダを作成し、storybook 設定を出力
  • package.json に storybook 向けの設定追加
    • devDependencies
    • scripts
    • eslintConfig.overrides

設定が終わったら以下のコマンドで storybook を起動します。

$ npm run storybook

ブラウザで storybook の画面が表示されたらOKです。

Storybook を触る

storybook では、 src/stories の中で定義された ストーリーに沿って、
Web 上での「カタログ」を生成していきます。

../src/**/*.stories.tsx 内で export された値はそれぞれ1ページとして
個別に storybook 上のカタログページとして表示されます。

::: messages
この設定は、.storybook/main.jsに記載されており、
後から自由に変更することができます。
:::

src/stories/Page.stories.jsx に記載されている play 関数は、storybook の特徴的な機能の一つです。
以下の例では、コンポーネントのボタンをクリックするユーザ操作を関数で指定して定義し、カタログページ上で自動実行するようにしています。

export const LoggedIn = Template.bind({});
LoggedIn.play = async ({ canvasElement }) => {
  const canvas = within(canvasElement);
  const loginButton = await canvas.getByRole('button', { name: /Log in/i });
  await userEvent.click(loginButton);
};

Storybook によるテスト

test-runner アドオンを利用することで、storybook で自動テストを実行することが可能です。

https://github.com/storybookjs/test-runner

まずは依存をインストールし、scripts セクションを追加します。

$ npm i -D @storybook/test-runner@0.6.4
package.json
{
  "scripts": {
    "test-storybook": "test-storybook"
  }
}

npm run 経由で実行すると jest が起動し、テストが実行されます。

$ npm run test-storybook

実行時に以下のエラーが表示される場合は、storybook の version を
0.6.4 に落として試してみると解決するようです。

TypeError: Jest: Got error running globalSetup - /Users/tomohiro.goto/mine/my-react-auth0-sampleapp-storybook/node_modules/@storybook/test-runner/playwright/global-setup.js, reason: Class extends value undefined is not a constructor or null

詳細は以下の Issue を確認してください。

https://github.com/storybookjs/test-runner/issues/203

正しくインストールできている場合、以下のような形でテストが実行されます。

$ npm run test-storybook            

> my-react-auth0-sampleapp-storybook@0.1.0 test-storybook
> test-storybook

 PASS   browser: chromium  src/stories/Header.stories.jsx
 PASS   browser: chromium  src/stories/Page.stories.jsx
 PASS   browser: chromium  src/stories/Button.stories.jsx

Test Suites: 3 passed, 3 total
Tests:       9 passed, 9 total
Snapshots:   0 total
Time:        6.426 s
Ran all test suites.

test-storybook では、それぞれの story が 自動的に spec に変換され、
基本的にエラーなく関数が表示できることが自動的に評価されます。

play function が設定されているコンポーネントでは、
それぞれの play function がテストとして実行されるため、
play function をテストコードのように用いることも可能です。

挙動に関する概要は、README の How it works のセクションでも解説されています。

https://github.com/storybookjs/test-runner#how-it-works

Discussion