テスト自動化とメテオフォール

# はじめに
この記事では、新規サービスで導入したE2Eテストと急な仕様変更での失敗談について話します。
ここでのE2EテストとはWebブラウザで表示されるサービスのUIを通して、アプリケーションが期待どおりにデータフローが適切に機能することを確認する手法のことを示します。

## テスト自動化の状況
当時サービスの大まかな流れとしては以下の図のように、会員になるための入会機能と会員になってから使用可能な会員機能に分かれていました。新規サービスということもあり、入会者を増やしたかったために入会機能だけはサービスダウンさせてはならないという方針がありました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154845/a52f818e-c2b0-ecc0-3984-6bb6b853c4fd.png" width=500 />

その当時はローンチまでの時間もあまりなく、テストのレイヤーによらずテストを書かずに機能を作成するという状態になっていたこともありました。そこで私はそれでは流石にマニュアルテストで毎回すべてを担保するのはさらに時間を要してしまうと思い、E2Eテストを導入することを打診しました。当時の私はE2Eテストが最強のテストだと思っており、シナリオがすべてのパターンが網羅してあり、それが全てパスできるようになっていれば、単体テストや結合テストをやる必要がない完全無欠のテストだと思っていたのです。
イメージとしては以下の図のように、E2Eテストは全てのテストを包含しているようなイメージを持っていました。（このイメージ自体は間違っていないかもしれません。）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154845/ed636a51-5478-a2e3-fb11-0d18375a3370.png" width=400 />

### 当時使用していたツール

当時使用していたライブラリとして、TestCafeを用いてJavaScriptでE2Eテストを実装していました。

https://testcafe.io/

TestCafeは素晴らしいライブラリです。他のライブラリでは必要なWebDriverのインストールが不要など環境構築が容易で、オープンソースであるために無料であり、比較的簡単に少ない記述量でシナリオを記述することができます。
基本的にはHTMLのDOMのプロパティなどで要素をチェックしたり、イベントを発火させるようなコードを書きます。ユーザが実際に操作するようにUIからバックエンドのリクエストまで一貫してテストできるのがメリットです。TestCafeのAPIを用いたコードを記述する必要があるため、やや学習コストがかかってしまいます。

他のメンバーに学習させる時間もなかったので、このTestCafeを用いて入会機能のテストケースを1人で網羅的に一挙に書いてしまいました。

### テスト自動化初動
テスト自動化の初動は良く、他のエンジニアの開発時間の確保と心理的安全性を保ちながら開発できるような環境になっていたと思います。

しかし、この平穏はすぐになくなってしまうのです。。。

## メテオフォールとは？

当時私のチームでは、アジャイル開発を実践しており 1週間を1sprintとしてサイクルを回して新機能をリリースしていました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154845/dbbc2dc0-1687-af25-39c2-2b9ba50189fc.png" width="500" />

しかし、日本の会社には神様のような天上人がいてひょんなことから突然の仕様変更があるのです。それは全てをぶち壊します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154845/2300cb2c-78ba-a998-3063-0736923423d1.png" width="500" />

### メテオフォールによる影響

その仕様変更は、入会機能の一新をするというようなものでした。開発していたコード自体は全て捨てる必要はなく、一部のサービスクラスやヘルパー関数など使いまわして対応できるものでしたが、UIのフロー全く違うものになっていたため、E2Eテストは全く使い物にならないものになってしまっていたのです。

また、その当時他の機能開発はストップしているわけでもなく、私自身は会員機能の開発に従事していました。なので仕様変更と共にE2Eテストが直せれば良かったのですがそんな時間も可能なメンバーもおらず完全に無駄なコードになっていました。
また、各機能の単体テスト等がなかったため、仕様変更による微妙なエッジケースや端境に対応できていないコードの使い回しが発生してしまっていました。これにより大規模改修後のマニュアルテストで大量の不具合が発生してしまい、メンバーの稼働が上がってしまうという状態になってしまいました。

## テストピラミッド

以下の図はテストピラミッドと呼ばれるものですが、ピラミッドの下位から上位に向かうにしたがってコストがかさむことを表しています。幅がテストケースの実行量を表現し、より下位のテストにテストケースを移動した方がコストの改善に繋がることを意味します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154845/9c3921bf-4505-e36a-6883-44da6dc0a13a.png" width="500" />

実際、私自身は高コストなE2Eテストで賄おうとしていたためメンテできるメンバーもおらず死ぬテストが生まれてしまいました。

### 意識すること
自動テストを作るときにはこのテストピラミッドを意識して、まずUnitTestを入れることを意識し細かな局所的なテストをするようにします。UnitTestを入れることを意識することでビューロジックとビジネスロジックに分けるコードを分離することを考え始めます。

### 実際やった改善
ビジネスロジックは、画面ごとに使用するサービスクラスにしっかりと分けJestでしっかりと端境を考慮したテストを実行するようにしました。

https://jestjs.io/ja/

また、TypeScriptによる型定義もサボり気味の部分があったのでテスト方針として静的テストであることをメンバーに共有し、Lintのルールを厳しくしたり、レビュー等で意識的に改善していきました。

https://www.typescriptlang.org/

ビューロジックについても、Storybookは導入済みでしたが、storycapとreg-suitによるVRTテストも実行するようにして、共通のコンポーネントが各ページに与える影響についても確認できるようにしていきました。

https://storybook.js.org/

https://github.com/reg-viz/reg-suit

https://github.com/reg-viz/storycap

この辺りを拡充してた所でようやくまた、E2Eテストについて検討する機会になって来ました。
この経験で決してE2Eテストが嫌いになったわけではなく、開発者の心理的安全性を下げたり、テストを効率化させる面では多大な威力を発揮するのでできるだけ導入はしたいと思っています。
しかし、おかれている状況とテストの特性を理解して、今のプロジェクトの状況に対してどのテストを拡充していくべきかを考えていく必要があります。

# T-DASHについて

https://service.valtes.co.jp/t-dash/

以上のことを振り返りながら、T-DASHを見てみると以下のような特徴・機能があることがわかりました。
当時このサービスを導入していたら大変な目にはあってなかったのかなぁと思ったりもしました（笑）。今回は実際に触れることはできませんでしたが、ぜひ試してみたいと思います。

- 日本語で書いたテストケースがスクリプトになる
T-DASHは日本語で書いたテストケースが、そのままスクリプトとして自動テストを実行できます。

- すぐに使えて操作が簡単
分かりやすいUI/UXなので、習熟時間も短くすぐにツールを使いこなすことができます。

- 画面定義機能があるため、要素が変更された場合に画面定義を変更するだけで一気にテストケースを修正できる



# 参考

https://service.valtes.co.jp/t-dash/


https://testcafe.io/

https://eiki.hatenablog.jp/entry/meteo_fall

https://dev.classmethod.jp/articles/testing_pyramid/