26
36

【Next.js】でStorybookを使用して自動テストのテストコードを書く。

Last updated at Posted at 2024-02-22

はじめに

こんにちは、エンジニアのkeitaMaxです。

前回の記事

前回作成したアプリをもとに開発していこうと思います。
今回は以下を目標としたいと思います。

  1. テストライブラリをインストールする
  2. Storybookでテストコードを書く。

1. テストライブラリをインストールする

npm i @storybook/testing-library
npm i @storybook/jest

上記コマンドでStorybookのライブラリのtesting-libraryjestをインストールします。

2. Storybookでテストコードを書く

インストールが終わったので早速テストコードを書いていきましょう。

要素の存在チェック

まずはbutton要素があるかどうかをチェックするテストコードを書いていきます。

まずは前回作成したindex.stories.tsxを以下のように修正します。

index.stories.tsx
import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { screen } from '@storybook/testing-library';
import { CountView } from '.';

const meta: Meta<typeof CountView> = {
  title: 'views/CountView',
  component: CountView,
  tags: ['autodocs'],
}
export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {
  args: {
    
  },
  render: function Render() {
    return <CountView />
  },
}
Default.play = async ({ args }) => {
  await screen.findByTestId('button');
  expect(button);
}

そして、index.tsのbutton要素を以下のようにdata-testid="button"をつけて以下のようにします。

index.ts > button
<button data-testid="button" className="bg-red-500 px-2 py-4 hover:bg-red-200" onClick={addCount}>
  カウントアップ
</button>

これで準備OK。以下のコマンドでStorybookを立ち上げましょう。

npm run storybook

そして、CountView > Default を開きます。そして下のほうにあるタブのinteractionを開くと、

image.png

このようになっていると思います。

PASSと書いてある下に緑のチェックが並んでいると思います。

これは、先ほど書いたテストコードが問題ないことを示しています。

画面に'button'があるのでテストが通っています。

ちなみにfindByTestIdで指定したものをbuttonからdummyに変えてあげると、

image.png

このようにFAILという文字とともに、テストが通らなかった項目の横に赤い四角が出てきます。

一番最初にdummyという要素を見つけることができなかったので最初の行で処理が止まっています。

ボタンクリックしたときの処理のチェック

Default.playの中を以下のようにしてみます。

Default.play = async ({ args }) => {
  const button = await screen.findByTestId('button');
  expect(button).toBeInTheDocument();
  await userEvent.click(button); //ここを追加
}

そしてまたStorybookの画面に行きましょう。

image.png

緑のチェックが増えました。増えたのがついかしたボタンクリックの処理です。
ボタンを押した証に、カウントする数字が0から1に変わっています。

次に、ボタンを押した後のカウントアップが正常にできるかのテストを書いた見ます。
Default.playの中を以下のようにしてみます。

Default.play = async ({ args }) => {
  const button = await screen.findByTestId('button');
  expect(button).toBeInTheDocument();
  expect(screen.queryByTestId('countText')?.innerHTML).toBe("0"); //ここを追加
  await userEvent.click(button);
  expect(screen.queryByTestId('countText')?.innerHTML).toBe("1"); //ここを追加
}

expect(screen.queryByTestId('countText')?.innerHTML).toBe("0");
ここでボタンを押す前のカウントが0であることを確認し、

expect(screen.queryByTestId('countText')?.innerHTML).toBe("1");
ここでボタンを押した後のカウントが1であることを確認しています。

実際の画面はこんな感じでした。

image.png

まとめ

今回使ったものをまとめます。

要素の取る

screen.findByTestId('{名前}');
screen.queryByTestId('{名前}');

ボタンの押す

await userEvent.click({要素});

存在を確認する

expect({要素}).toBeInTheDocument();

とった要素の中身があっているかの確認方法

expect(screen.queryByTestId('{名前}')?.innerHTML).toBe({確認したい値});

おわりに

こんな簡単に自動テストを書けると思いませんでした。

今後ももっと自動テストを学習していって楽にバグの少ないプログラムが書けるようにしていきたいと思います。

使い始めたばかりで、使い方が間違っていたり、もっといいやり方を知っている方がいたら、コメントで教えていただければ幸いです。

最後まで読んでいただきありがとうございました。

参考文献

まとめの記事

26
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
36