バックエンドエンジニアが、半年間フロントエンドのテスト自動化に取り組んだ結果、、！

## 背景

私は主にバックエンドの実装メインで業務をこなしてきましたが、直近でモダンなフロントエンドアプリの開発に携わりました。

その際、品質担保を自動化してもっと楽できないかな?とフロントエンドの自動テストに試行錯誤したので、これからフロントエンドテストの自動化に取り組む方の参考として、この記事を公開します。

## PJの前提

- 使用技術
    - Vue 3
    - TypeScript
- 設計
    - [Atomic Design](https://bradfrost.com/blog/post/atomic-web-design/)を採用

## PJでの自動テスト導入事例

### 1. デザインカンプのコンフリクト

PJでは[Atomic Design](https://bradfrost.com/blog/post/atomic-web-design/)を導入していたため、大量の小さなコンポーネントを作成します。

これらのコンポーネントの見た目を確認するため、開発当初は一つのVueファイルに作成したすべてのコンポーネントを記載していました。

この方法はシンプルですが、下記のようなデメリットがありました。

- チーム全員が同じVueファイルで同時に作業するため大量のコンフリクトが発生
- コンポーネントの場合分け(エラー発生時の表示など)の記載漏れも多い

#### 【解決策】Storybookの導入

そこで[Storybook](https://storybook.js.org/)を導入しました。

Storybookは簡単に言うと、それぞれのコンポーネントごとに開発を進められるようになるツールで、そのままデザインカンプとして利用も可能です。

![Storybook_display.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290859/328ddae9-f00b-7f00-dff5-388fc544c90e.png)
https://storybook.js.org/

これにより、コンポーネントを個別に開発することが可能になり、動作確認や表示の場合分けなど、デザインカンプのコンフリクトを気にせず開発できました。

#### 【注意点】 

導入の注意点としては

- 開発初期からコンポーネントを分割していないと効果が薄い[^1]
- コンポーネントをStorybookに表示するためのファイルを作成する必要がある[^2]

などが挙げられるため、早い段階でStorybookを導入することがポイントです。

### 2. コンポーネントのデザイン崩れの見逃し

Atomic Designでは、AtomやMoleculesといった分類で小さな子コンポーネントを組み合わせてページ全体を構成します。

そのため、コンポーネントの依存関係が多く、子コンポーネントの修正がそれを使用する親コンポーネントに影響を与えます。

![atomic-design.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290859/dce54639-583c-0a47-5a3e-6157b62132f6.png)
https://bradfrost.com/blog/post/atomic-web-design/

PJでは

- ボタンのコンポーネントを変更してフォームのコンポーネント崩れが発生する
- UIライブラリのマイナーバージョンアップデートでで広範囲のコンポーネントが崩れる

などの問題が発生し、人の目で確認していたため、コンポーネント崩れの検知漏れを起こしていました。

#### 【解決策】VRT (Visual Regression Testing)の導入

コンポーネントのレイアウト変更検知を自動化すべく、VRT (Visual Regression Testing)を[storycap](https://github.com/reg-viz/storycap) x [reg-suit](https://github.com/reg-viz/reg-suit)で実現しました。

内部的には、storycapでコンポーネントごとにキャプチャをとり、変更前後のキャプチャをreg-suitで比較する、という仕組みになっています。(比較結果はAWS S3にCIでアップロードしています。)

![chrome_desktop@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290859/63c7f902-cc97-97bb-c405-004e2b99d54e.png)
https://reg-viz.github.io/reg-suit/

#### 【注意点】 

storycap x reg-suitの導入にあたり、注意点としては

- インフラの設定コスト
    - S3などのストレージ [^3]
    - GitHub ActionsなどのCIツール
- 日付表示などは差分が出やすいため、変更検知結果が偽陽性にならないように、コンポーネントの表示は工夫が必要

などが挙げられます。

-----------------------
### 3. コンポーネントの動作のデグレ 

前述のVRTでコンポーネントの見た目の変化を検知はできましたが、動作のデグレに関してはまだ手が届いていません。

PJの例では、複雑な動作のコンポーネントが多く、手動の確認は手間で、フォームのバリデーションや、ボタンのクリックイベントなどが気づいたら動いていない、ということが多々ありました。

#### 【解決策】 (PoC中) Vue Test Utilsの導入

そこで、[Vue Test Utils](https://test-utils.vuejs.org/)を導入し、コンポーネントの動作テストの自動化を検討しています。

Vue Test UtilsはVueのテストユーティリティで、Vueコンポーネントのテストを行うためのツールです。

これはボタンの押下などの動作をエミュレートし、動作確認を自動化することができます。

```typescript
// https://test-utils.vuejs.org/guide/essentials/a-crash-course.html
test('todoを追加する', async () => {
  const wrapper = mount(TodoApp) 

  // フォームに入力
  await wrapper.get('[data-test="new-todo"]').setValue('New todo')

  // フォームを送信
  await wrapper.get('[data-test="form"]').trigger('submit')

  // todoが追加されていることを確認
  expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(2)
})
```

#### 【注意点】 

導入の注意点としては

- Vue Test Utilsの学習コスト
    - 独特の記法になれる必要がある [^4]
- Vue Test Utilsの機能が若干限られている?
    - ex. 操作対象の要素のセレクタは`data-test`属性を使う? (公式のサンプルコードは`data-test`属性を多用している)
    
など、コストに対するリターンを考慮しながら導入を検討する必要があります。
私的な考えですが、アプリのコアとなる動作に対して重点的にテストケースを書く使い方が良いと思います。

## まとめ

フロントエンドテストの自動化は、開発スピードの向上など、フロントエンド開発のレベルを上げる可能性を秘めています。

フロント専門でない私でも、特に苦もなく導入できたため、是非検討してみてください。


[^1]: 既存プロダクトのコンポーネント分割の布石とすることは可能か？
[^2]: 本PJでは、VueをStorybookで表示するのは若干くせがあるため、`args`などの記載は後回しとして、とりあえず表示だけ確認しました
[^3]: クラウドストレージを使用しない手段も有るようです。
[^4]: とはいえ、そこまで機能も多くないため、JavaScriptに慣れている方であれば、すぐに使いこなせるはずです。