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


# はじめに

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

前回の記事

https://qiita.com/keitaMax/items/ca9692a20d9227f7e3a6


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

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

# 1. テストライブラリをインストールする
```
npm i @storybook/testing-library
npm i @storybook/jest
```

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



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

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

### 要素の存在チェック

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

まずは前回作成した`index.stories.tsx`を以下のように修正します。
```react: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"`をつけて以下のようにします。
```react: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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/9251af72-e793-cbab-e9f8-e12705096ae6.png)

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

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/3fbaadfe-2970-4d2e-f016-e1b2e6b9ed43.png)

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

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

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/1f74b5b9-e2f8-3ba3-6655-3e775ef1678b.png)

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

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

```react
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");`
ここでボタンを押した後のカウントが１であることを確認しています。

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/65a48066-2b0d-bae8-0e09-6a394355931a.png)

# まとめ

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

### 要素の取る
```react
screen.findByTestId('{名前}');
screen.queryByTestId('{名前}');
```
### ボタンの押す
```react
await userEvent.click({要素});
```
### 存在を確認する
```react
expect({要素}).toBeInTheDocument();
```
### とった要素の中身があっているかの確認方法
```react
expect(screen.queryByTestId('{名前}')?.innerHTML).toBe({確認したい値});
```


# おわりに

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

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

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

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

# 参考文献

https://qiita.com/punkshiraishi/items/da9a221c7423f6f2d1c9

https://testing-library.com/docs/queries/about/#types-of-queries

https://www.npmjs.com/package/@storybook/testing-library

https://www.npmjs.com/package/@storybook/jest


# まとめの記事

https://qiita.com/keitaMax/items/cb0cb4b107fdacb417d7