テスト自動化のあるある失敗例と成功例

この記事は [テスト自動化あるある言いたい by T-DASH Advent Calendar 2024](https://qiita.com/advent-calendar/2024/t-dash03) のシリーズ2 20日目の記事です。

過去以下のようなテスト自動化の記事を投稿してきました。

https://qiita.com/bon10/items/9eab78e7a0c150dd4efe

https://qiita.com/bon10/items/5a6d2b8c477ffcc41978

今回はテスト自動化に携わってきた中で経験したよくある話を良し悪しそれぞれ書いてみます。


## QAが始めたテスト自動化

### 悪い例: 組織に浸透しない問題

QAのメンバーがリグレッションテストや手動テストで毎回反復して行っているテスト、バグがよく出る項目のテストなどをE2Eテストで自動化すると、エンジニアからは「それはQAの役割だよね、ありがとう」と言われるものの、特に品質改善のアクションが生まれない。
そこで組織的にプロダクトの品質を改善するためにCTOやマネージャーがようやくメスを入れ始めても、今度はエンジニアが「これじゃだめだ」とE2Eテストの品質にダメ出ししてきてなんかよくわからないうちに責任の所在が有耶無耶になる。（結局エンジニアはなんだかんだ品質改善に取り組まない）

### 良い例: エンジニアが組織を巻き込む

QAのメンバーがクラウドテスティングサービスやSeleniumのブラウザ拡張機能でポチポチやって作ってたExcel(スプレッドシート）管理のE2Eテストに対して、「コスパ悪すぎ」とイチャモンつけてくるエンジニアが、Playwright、Puppeteerなどで書き直しGithubでコード管理をし始める。
その後テスト全体の効率化と高コスト化を図るために、愚直なHAYST法から2因子間網羅や条件網羅の一部簡略化を図ったり、境界値・限界値などのブラックボックステストを一部ホワイトボックステストに移行（単体テストで担保）したりする。
結果、単体テスト・結合テスト・E2Eテストのバランス感がエンジニアとQAの間で共有されることとなり、プロダクト全体の品質についても組織単位のKPIや施策が生まれてハッピー。

---
テスト品質はQAですべてが決まるわけではありません、という当たり前の事実をエンジニアにも意識してもらう必要があります。
私の経験では、 __改修実装については、テストコードを含まないPRは理由がない限りマージしない__ という強制ルールを敷いたこともあるくらいです。
また、エンジニアがQAに介入することで組織横断的な動きも少しながら生まれてきます。俗に言う「越境」というやつですね。
テスト品質（特に単体・結合にかけて）に問題を抱えている組織のマネージャーは、こういう動きをしているエンジニア・QAのメンバーを意図的に異文化交流させてあげるくらいの行動をしたほうが良いでしょう。

## 自動テストのコード

### 悪い例： 計算ロジックを画面から取ってきて、別画面の値と比較

QAエンジニアのAくんは、商品購入のフローで、税率・送料・手数料の計算後の合計値を画面から取得し、その値を注文履歴画面の合計値と比較する自動化コードを書いていた。
頑張ってXPathやCSSセレクタを書いてテーブルから値を取得し、それぞれの足し算をコード側で実装。これを購入画面と注文履歴でそれぞれ実装。

### 良い例： 固定値を定義し、画面上の値と比較

QAエンジニアのBくんは、「実装がデグレードしたりバグったとき、本来正しい値って何かわからなくなりそうだ」というリスクを回避するため、自動化コード上に固定値として商品の金額、税率、送料などを定義。その値を購入画面、注文履歴画面それぞれで比較するように実装。

---
テスト対象によってこのセクションの良し悪しは別れるかもしれません。
しかし、個人的に実装の改修によってデグレードしたりバグが検出されるとき、ロジックのどこに問題があったかをコードの中身を知らないQAでも検知できる後者（良い例）のほうが望ましいと私は考えています。
なのでE2Eでのテストは、基本的にはブラックボックステストのはずなので計算ロジックを無視して固定値を使うほうが理に適っていると思います。
それに「仕様として正しい値の計算ロジックを画面から取得」の場合、商品購入と注文履歴のどちらの計算ロジックにもバグが含まれてしまった場合、計算ロジックを画面から取得するコードの場合 __「値が間違えていても正しい」というテスト結果になってしまいます。__

例えば特定のクレジットカード会社のキャンペーンで、そのカードブランドだけ手数料が0円になる要件が追加。エンジニアはその対応のため、特定カードブランドだけのロジックを修正したつもりでしたが、電子マネーで支払ったときも手数料が0円になってしまうバグがあったときを考えてみましょう。

固定値だと特定カードブランドのテストと電子マネー決済の療法がエラーで引っかかります。（手数料分合計値がズレるため）
しかし、計算ロジックを画面から取ってきているとテストはどちらもエラーになりません。
これでは、__E2Eテストがデグレを判別できなくなってしまいます。__

無論、QA（またはQAエンジニアやエンジニア）が事前に改修内容を把握したうえで該当しそうなE2Eテストを見直して改修できればそれがベストです。が、これを実施できる組織はかなりテストに対する考え方が成熟している場合に限るのではないかと思います。

## E2Eテスト

### 悪い例: 便利だから手作業でやってるテスト全部移行しようぜ

Tさんは機能のテスト30件をとあるクラウドの自動テストツールに移行させました！
その結果ボタン1つで当該機能のテストを実施できるようになり、日々の改修による要件や仕様の変化、デグレード、テスト内容の修正などもわかるようになりました。
その後、残り全機能の400件を自動テストに移行しようと奮闘中。ただし、1人では時間がかかりすぎるので3名程度のQAを追加！
その半年後、400件のテスト移行が終わったものの、月間のテスト実行回数の制約により使用料が増えることに。さらに開発チームから「UI刷新するわ」という来季の目標が提案され、430件のテストの修正範囲を洗い出すことに。
修正対応中のコストは普段の3倍。自動化ツールのランニングコストが一時的にQAの人件費を上回る結果に経営陣から「弾幕濃すぎ！何やってんの！」とお叱りの言葉が。。。

### 良い例: 単体・結合テストレベルのものはそっちでやってもらう

Yさんはとある機能のテストを30件をとあるクラウドの自動テストツールに移行。
その後過去のバグ分布図や分析表と比較し、問題のありそうな機能のテストを一部自動テストに移せないか上司に打診。
上司からは「開発チームと同期を取って、テスト範囲と責任範囲を役割分担してみたら？」とアドバイスが。
開発チームの週次定例にQAも参加するようになり、自動テストツールで対応する部分と、並列処理できそうなで対応する部分のテストを分割し、エンジニアと都度合意を取るように。
結果、問題の多かった機能60件を自動テストツールに移行し、140件が手動テスト、残り200件はテストを分解し、エンジニアにモックデータやスタブなどを使った単体・結合テストに置き換えてもらうことに。

---

E2EテストはGUIや外部システムに大きく依存しているので、それらの変更時の対応がものすごく大変です。またブラウザを通じてユーザーや運用側のユースケースを始まりから終わりまでテストするため、テスト時間もかなり要します。多分Tさんの作ったテストは、12時間くらい時間がかかることでしょう。なるべくE2Eのテストを減らすことで、テストの実装・修正コストと実行時間の増加を抑えることが重要です。
この話はテストピラミッドの話が詳しいためそちらを参照してください。

https://gihyo.jp/dev/serial/01/savanna-letter/0005

## 担当者

### 悪い例： テスト自動化担当者が1人で孤軍奮闘
頑張ってテスト自動化したものの、後任者が現れずテスト自動化の価値もあまり広まらず、モチベーションがダウンして退職・打ち切りEND。

### 良い例： テスト自動化担当者とフォロワーが組織に伝搬
なんだか最近QAから具体的かつピンポイントな指摘が多くバグもしっかり抽出されていることに気づいたエンジニアチームが、テスト自動化に興味を持ち始める。
さらにテスト自動化を自分もやりたいというQA担当者が現れはじめ、QA・エンジニア組織全体での品質改善の視点にテスト自動化が加わる。

---

これはテスト自動化担当者が頑張る面もあれば、それを周りに広める役目となるフォロワーが存在するか、あるいはマネージャー層がKPI作ったり品質向上の施策を組織全体に義務付けるかなどの取り組みが必要になるでしょう。その性質から、良い例については再現性が明確ではないため、注意深く状況を把握し、テスト自動化の施策を進めていくこともまた重要だと思います。
悪い例については再現性が高いので、こちらは眺めているだけでもすぐに気付けるはずです。（四半期、または半期のタイミングで成果が停滞し始めたら注意）


以上、テスト自動化あるあるでした！