🧪

Nuxt(SPAモード)の自動テストを考える

2022/02/12に公開

はじめに

  • NuxtのSPAモードの時の自動テストを計画・運用した時に問題が発生しました。問題を改善していった結果、自動テストの分類などを個人的にしてみたのでこの記事ではそれをまとめます。
  • 忙しい方はテストサイズまとめ自動テストの分類まとめに内容がまとまっているので、そちらを確認ください。
  • ちなみにこの記事ではテストコードの書き方については記載しませんのでご了承ください。

対象読者

  • 自動テストの運用を初めてみたい方
  • 自動テストを導入しても上手く運用できない方
  • 自動テストが肥大化してCI管理が上手く出来ていない方

想定環境

以下の環境で開発進めていることを前提に進めます。

テストサイズについて

参考資料

自動テスト時のテストサイズの考え方については以下のサイトや本に記載されています。今回の記事ではそれをベースに独自の見解でまとめていきます。

テストサイズまとめ

Nuxt(SPAモード)の場合、自動テストのテストサイズをチーム内で定義した方が良いです。チームの自動テストの習熟度にもよるので、あくまで参考値として見て頂ければと思います。
今回は以下のテストサイズをベースに自動テストの分類をしていきます。

テストサイズ 1テストケースの実行時間 ネットワーク/ファイルアクセス CI連動
Small 100ms未満 モックのみ Git push時
Medium 1秒未満 localhostのみ PullRequetマージ時、ステージング環境リリース時
Large 制限なし 制限なし ステージング環境リリース時、本番環境リリース時、夜間定期実行

自動テストの分類

分類の前提について

上記で説明したテストサイズの他にテストの観点ベースで分類していきます。
システム規模によってはテストサイズごとにまとめてしまっても問題ありません。
チームとしてどこの品質担保が弱いかなどを話し合って部分的に導入する場合もあります。

ユニットテスト

  • テストサイズ:Small
  • 対象ファイル:設定ファイル以外の全てのファイル
  • テスト対象:publicメソッド
  • テスト内容:メソッドの処理が想定通りかテストする
  • 期待出来る効果:メソッドの挙動にデグレがないか確認できる
  • Componentのmount方法:shallowMount
  • モックの適応範囲:テスト対象ファイル外は全てJestのモック
  • メモ:
    • カバレッジを測定することでテストがどこまで網羅しているか確認できる。
    • 異常系やprivateメソッドで到達しにくい箇所もあるのでカバレッジ100%は目指さないようにする。

スナップショットテスト

  • テストサイズ:Small
  • 対象ファイル:components/pagesの.vueファイル
  • テスト対象:templateのv-if, v-forに対応するdata/props/computed/methods
  • テスト内容:
    • コンポーネントのDOM構成が想定通りかテストする
    • templateのv-if, v-forが切り替わるテストケースを準備する。
    • JestのtoMatchSnapshotを使用してDOM構成を保存する。
    • 次回変更時にDOM構成にデグレがないかチェック出来るようになる。
  • 期待出来る効果:DOM構成にデグレがないか確認できる
  • Componentのmount方法:shallowMount
  • モックの適応範囲:テスト対象ファイル外は全てJestのモック
  • メモ:
    • templateのv-if周りが複雑化している場合のデグレチェックとして役に立つ。スナップショットテストを記載後にtemplate側のリファクタリングを行うとよい。

コンポーネント結合テスト

  • テストサイズ:Medium
  • 対象ファイル:pagesの.vueファイル
  • テスト対象:publicメソッド
  • テスト内容:
    • ページごとの操作に対してテストする
    • コンポーネントを結合して、props/emitが正常にコンポーネント間で連携するか確認する
  • 期待出来る効果:ページごとの操作にデグレがないか確認できる
  • Componentのmount方法:mount
  • モックの適応範囲:ネットワーク/ファイルアクセスはJestのモック
  • メモ:
    • propsまわりの変更がある場合にtoMatchSnapshotを使用してDOM構成をチェックするのもあり
    • テストケースがユニットテストと重複しやすいので、コンポーネント間連携の操作を優先してテストすると良い

ネットワークアクセステスト

  • テストサイズ:Medium
  • 対象ファイル:ネットワークアクセスをしているファイル
  • テスト対象:ネットワークアクセスをしているメソッド
  • テスト内容:ajax処理が正常に動作するかテストする
  • 期待出来る効果:ajax処理でデグレがないか確認できる
  • Componentのmount方法:shallowMount
  • モックの適応範囲:
    • ネットワーク/ファイルアクセス以外はJestのモック
    • ajaxのアクセス先はテスト用のAPIサーバーを立てるのが望ましい
    • JSON ServermswなどをAPIサーバーとして使用しても良い
  • メモ:
    • コンポーネント結合テストに含めても結合テストとして扱ってもよい。
    • 観点を分けたり、テスト実行を分離したりしたい場合に分ける感じ。

ビジュアルリグレッションテスト

  • テストサイズ:Medium
  • 対象ファイル:componentsの.vueファイル
  • テスト対象: -
  • テスト内容:コンポーネントのデザインにデグレがないかテストする
  • 期待出来る効果:コンポーネントのデザインにデグレがないか確認できる
  • Componentのmount方法:-
  • モックの適応範囲:StoryBook関連のモックライブラリを使用
  • メモ:
    • 2022年2月現在、Storybook + Storycap + reg-suit を連携してビジュアルリグレッションテストを実施するのがメジャーかな
    • Storybook を使用していない場合、新規にStorybookのコードを書いたり、メンテナンスする必要があるので費用対効果を考える
    • CSSまわりのスタイル崩れのデグレが頻繁に起こっている場合は導入した方がよい

e2eテスト

  • テストサイズ:Large
  • テスト内容:
    • ユースケース・シナリオベースでテストする
    • Docker上で本番環境に近い構成にして実際にWEBサーバーに配置してテストする
    • jestからpuppeteerselenium-webdriverなどを使用してWEBページを操作する
  • 期待出来る効果:テストしたユースケース・シナリオの動作にデグレがないか確認できる
  • メモ:
    • 改修によって影響を受けやすい箇所なので、テスト数は極力少なめにしたい
    • jest-image-snapshotなどで実際に表示されているWEBページの画像をスナップショットテストするのもよい

パフォーマンステスト

  • テストサイズ:Large
  • テスト内容:
    • ページ単位のレンダリングが想定通りかどうかテストする
    • ページに最大数のデータをレンダリングして想定通りの描画時間になるかテストする
    • APIのテストはバックエンド側で実施するのでフロント側のパフォーマンステストには含めない
  • 期待出来る効果:想定した時間でレンダリングできることを確認できる
  • モックの適応範囲:テストケースごとに適宜使用
  • メモ:
    • e2eテストとちがいレンダリング速度を測定したいため、APIなどはモックでもよい

自動テストの分類まとめ

テストサイズ テスト分類 Componentのmount方法 モックの適応範囲 テスト内容
Small ユニットテスト shallowMount テスト対象ファイル外は全てJestのモック メソッドの処理が想定通りかテストする
Small スナップショットテスト shallowMount テスト対象ファイル外は全てJestのモック コンポーネントのDOM構成が想定通りかテストする
Medium コンポーネント結合テスト mount ネットワーク/ファイルアクセスはJestのモック ページごとの操作に対してテストする
Medium ネットワークアクセステスト shallowMount ネットワーク/ファイルアクセス以外はJestのモック ajax処理が正常に動作するかテストする
Medium ビジュアルリグレッションテスト StoryBook関連のモックライブラリを使用 コンポーネントのデザインが想定通りかテストする
Large e2eテスト ユースケース・シナリオベースでテストする
Large パフォーマンステスト 適宜使用 ページ単位のレンダリングが想定通りかどうかテストする

おわりに

  • 自動テストの分類わけやCI時に何をテストなどに悩んだ場合にこの記事が役に立てばうれしいです。
  • Nuxt以外でもVue.jsやそのほかのSPAフレームワークでもこの考えは適応できると思うので、他のフレームワーク使用時に提案してみようと思ってます。

Discussion