あなたが自動テストを行う目的は何ですか？

この記事は[ソフトウェアテスト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/softwaretesting)の24日目です。
前日の記事はまつや大先生の[クリスマススペシャル 「AIが使われたオススメ機能」のテストのやり方](http://testerchan.hatenadiary.com/entry/2019/12/23/080000)でした。そういえば書籍化決定したそうですね！！！おめでとうございます！！！


### TL;DR

- 緑色の会社のテスト自動化/SETチームのマネージャー( https://twitter.com/ozonohiroaki )
- スクラッチから自動テストを始めたときの失敗談
- 目的って大事


# はじめに
もともと今回のアドカレではゴリゴリの技術記事を書かせていただく予定にしていたのですが、あるツイートの反応を受けてちょっと内容を泥臭いものに変更させていただくことにしました。
そのツイートというのがこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">福岡でテスト自動化ミートアップしようと思ってるんですが需要ありますかね？<br>気付けば丸3年で相当な数の失敗経験させていただいてることに気付き。<br>今からやりたい人には「こんな落とし穴が...」を、今やってる人には「良かった私だけじゃなかった」という共感を提供できそう</p>&mdash; ozono (@ozonohiroaki) <a href="https://twitter.com/ozonohiroaki/status/1199223446229532674?ref_src=twsrc%5Etfw">November 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

そんなわけで、タイトルは釣りでも煽りでもなんでもなく、私が自動テストに取り組む上でもっとも大切だと思うことをストレートに表現してみました。
まったくもって自慢にもならないんですが、右も左もわからないスクラッチから自動テストに取り組み、専門の組織を自ら作り、丸3年様々なプロジェクトで運用してみた結果、 **失敗した数だけは多分誰にも負けない** というよくわからない自負があります。

私よりうまくやっている例は日本にも世界にもごまんとあるでしょう。
先々を見据え、私が躓いてきた小石をひょいひょいと躱している方々もたくさんいることでしょう。

ただ、社内外の話を聞いているとどうやら同じような局面で同じように悩んでいる方がそれなりにいらっしゃるように感じています。私の失敗談がみなさんの自動テストをもっと素敵にするお手伝いができたとしたら、これ以上の幸せはありません。
おそらく私の経験談は自動テストに関わるいろんな方の参考になれるかと思いますが、特に **今から専門の組織を作ろうと思っているマネージャーさんたち** に読んでもらいたいと思っています。上司から **「コスト削減したいから自動テストやってみてよ」** ってふわっと無茶振りされたあなた、ぜひこの記事のリンクを無言であなたの上司にぶん投げてやってください。

この記事は

- 導入編
- 運用編

の2つに分けて私の実体験をもとにお話します。
注意点をいくつか。

- この記事では`自動テスト == E2EのUIテスト。ブラウザやエミュレーター、実機などをプログラムで操作して行うテスト`として定義しています。
- この記事はあくまで**こうやって失敗した**という経験のシェアを趣旨としています。決してこうすると**絶対に失敗する**、もしくは反面教師にすれば**絶対に成功する**ということではありません！
- 私の所属する組織は開発組織とQA組織がそれぞれ独立しています。私の経験談はこのバックグラウンドに起因する問題が多いことをあらかじめご了承ください。
- ところどころボカしますが、結構生々しい話をするため事前に登場人物には許可をもらった上で会社の広報からレビューを受けています。
- 細かい技術の話は今回しません。需要があればまたいずれ。

# 導入編
自動テストを実際に実装し始める**前**、あるいは自動テストを専門として行う組織やチームを作る**前**の段階で考えておいたほうがいいことに関して。
## その1 あなたが自動テストを行う目的は何ですか？
初っ端でタイトル回収しちゃいました。
というか導入編はこれ一個だけです。
そして、おそらく**これ以上大事なことは**ありません。

**あなたが、もしくはあなたの上司が、自動テストをあなたの会社に導入しようと思っている理由は何ですか？**

これは自動テストをやりたいんですが〜と相談を受けた際、私が必ず最初に聞くようにしていることです。
おそらくいろんな理由があることでしょう。

1. プログラミングを仕事にしたいから
2. テスト自動化エンジニアという新しいキャリアを作りたいから
3. 他所の会社や他所のチームは自動テストを導入してるし、うちのチームでもやりたいと思っていたから
4. 手動テストのコストを減らしたいから
5. 手動テスターの負担を減らしたいから

ざっと挙げてみましたが、これらは全て今の会社で実際に話があがったものばかりです。
大別すると1~3のような`キャリアに関する観点`と、4~5のような`コストに関する観点`の2つに分けられそうです。
これらが自動テストをやる目的として列挙された場合、**私はだいたいの場面において警鐘を鳴らします**。本当に大丈夫？と。

わかりやすく説明するために、まず私の経験したお話からさせていただきます。
私は手動テスターとして今の会社に入社し(と言っても半年もやってないですが。。)、当時のQA組織に発足していた自動テスト研究会的な集まりに招待されました。
当時の研究会のメンバーはみなさん自分のプロジェクトに関する仕事で手一杯。かたや入社したばかりの私はそこまで忙しくなかったし、プログラムを書くことは全く苦でなかったので、自動テストに関するデモをたくさん作っていきました。
当時の上司は「お、これはいけそう！」という手応えを掴んだのでしょう。じゃあこれをある研究会メンバーがテストしていたプロジェクトでやってみよう！と、トントン拍子で話が進み、これが私が自動テストエンジニアとして関わる初めてのプロジェクトになりました。

ここまで聞いて勘が良い方はすでに気づいているかもしれません。
上に挙げた5つの理由と、私と当時の上司が自動テストを始めた理由に共通すること。
それは、

**プロジェクトをどう良くしたいのか**

という観点がすっぽり抜け落ちてしまっていることです。
私の当時の上司はおそらく`キャリアに関する観点`、私自身は`コストに関する観点`の意識が強かったように覚えています。**これが私と私の当時の上司が犯した1番大きな失敗です。**

### 手段の目的化
お気付きのとおり、`キャリアに関する観点`は明らかに**手段が目的化**してしまっています。
これは特に現時点で全く自動テストが普及していない組織やチームで起こりがちな話だと感じています。
私は自動テストを始める**動機**として`キャリアに関する観点`があるのは別に悪いことではないと思います。ただし、その場合上司が部下のモチベーションをプロジェクトへ利益として還元できるよう、部下を**誘導**してあげるべきです。さもなくば最悪あなたの部下は**潰れます**。

自動化ハイなんて言葉がありますが、実装を担当する部下本人は**プログラムを書くこと**が目的になってしまう可能性が高く、プロジェクト全体が見えていないかもしれません。このとき一番最悪なのは、**「よし！じゃあ好きにしていいよ！」**と上司が放置してしまうことです。
上司がサービス開発を経験したことがない場合にこのような場面をよく見てきましたが、**自動テストを運用することはある種サービスを作ることと同等の大変さがあります**。
部下がプログラミング経験あるから、あるいは上司がプログラムわからないから、という理由でコミニュケーションが不足してしまっていませんか？

**あなたたちの目的は自動テストを書くことですか？プロジェクトをよくすることでしょう？**

当時の上司と当時の私に1000回くらい言って聞かせてあげたいです。

### コストの削減
次によく聞くモチベーションとして`コストに関する観点`があります。
昨今のRPA(Robotic Process Automation)ブームしかり、手動でやっていることをプログラムを組んで自動で行うことで、今手動テストにかかっているコストを削減したいという目的が掲げられることも多いように感じます。
なにを隠そう、先に述べたとおり私自身もコスト削減を一丁目一番地に掲げていました。
コストと言ってもいろんな種類がありますが、ここでは**人的コスト**に絞り、まず結論から書きます。

**自動テストで人的コストを削減するのは至難のわざです。**

丸3年の経験でたくさんのプロジェクトへ関わって来ましたが、ついぞ人的コストを削減したという実績は残せていません。
例えば先ほど話に出した私が初めて関わったプロジェクトに関して言うと、今では様々な環境・デバイスで3000以上のテストケースを運用しています。これを**手動で約4人日かかっていたテストを1人日以下にしました！**という風に人的コスト削減を声高にアピールすることはできます。局所的に切り取ればいくらでも数字はよく見せられます。
ただしこれはあくまでミクロ的なQA視点で見た場合であって、実際はここにシニアの自動テストエンジニア1人 + 自動テストエンジニア1~2人がつきっきりで関わっています。
つまり、マクロ的にプロジェクト全体を俯瞰した場合、**人的コストは減るどころかむしろ増えている可能性さえあります。**

これは自動テスト特有の性質が大きく絡んできます。
![Mike Cohnのテストピラミッド](https://www.mountaingoatsoftware.com/uploads/blog/Testpyramid.jpg)
ref. https://www.mountaingoatsoftware.com/blog/the-forgotten-layer-of-the-test-automation-pyramid

上の図はTest Automation Pyramidと呼ばれるもので、おそらくテスト自動化業界で一番有名な図です。
簡単に説明すると、上に行けば行くほどコストが高いことを示し、下に行けば行くほどROI(Return on Investment: 費用対効果)が高いことを示しています。
そう、UIの自動テスト、つまり**Pyramidの頂点を実装あるいは運用すること、それ自体がコストが高いことなんです。**
コストが高いものでコストを削減する。なかなかにハードな匂いがしますね。
自動テストはなぜコストが高いのかに関しては多くの方が述べられているのでそちらに譲ります。

### その結果どうなったか

こうして私は人的コストを削減するために必死で自動テストを書いて、書いて、書いて。壊れては直して、直して、直して。
毎日朝早くから誰より遅くまで自動テストと向きあいました。
しかし、一向に減らない人的コストに頭を抱える日々。
200テストケース近くを実装したとき、すでに半年以上が経過していました。
しかし、未だQAの人的コストは目に見えて減らず。
焦るあまりテストケースを増やすことにだけ集中してしまい、不安定なテストが量産され、メンテナンスできず次第に壊れていくテストケースの数々が積み重なっていきました。
人的コスト削減どころか、不安定なテストの結果自体を誰も信用しなくなり、次第になんのために自動テストやってるんだっけ？という空気がプロジェクト内に漂うようになりました。
自動テストはただ実行されているだけで、誰もその結果を活用していないという最悪の状態にまで陥ってしまいました。

もし私がこのとき、

- 手動テストでカバーできていない部分を自動テストでカバーして、ユーザー体験をよりよくしたい。
- 本番環境で起きるサービスの障害を自動テストでひとつでも減らし、機会損失を減らしたい。
- 開発のライフサイクルを改善するために自動テストを活用して、エンジニアがもっと仕事しやすい環境を作りたい。

こんな目的を持っていたらどうだったでしょうか。
こうやってプロジェクトに貢献したい、ということを関係者と話していたらどうだったでしょうか。
あるいは、人的コスト削減はちょっと難しいかもです。。と正直に打ち明け、打開策を一緒に探していたらどうでしょうか。
少なくとも、焦って無茶をすることはなかったでしょう。
つまり、**人的コストを削減する**という無謀な挑戦に囚われず、**いかにプロジェクトに貢献したいか**ということにフォーカスを合わせて関係者と意識の共有が出来ていたら、たとえ自動テストを始めた動機が手段の目的化のようにズレていたとしても、少しずつ軌道修正して良い結果を出せていたかもしれません。
当時の私は残念ながらこの考えに至らず、方向を修正することができず、見栄えの良い数字を並べては効果が出ているようにアピールするだけで、実際は**およそ1年以上**プロジェクトに対する利益をなにも出せず苦悩する時間を過ごすこととなりました。
この窮地を救ってくれた相棒と、あるエンジニアの話はいずれまた。

余談ですが、これらの経験が今の私のベースとなり、ミートアップやカンファレンスで登壇させていただく際にはほとんどの場合で**「うちのチームは人的コストの削減は狙っていません」**とお話させていただくようになりました。

# 運用編
いざ自動テストを試してみて、パイロットプロジェクトである程度の手応えを感じたら、次に考えるのはこの自動テストを**どう運用していくか**、あるいは**いかにこの取り組みをスケールアウトさせるか**ということになるかと思います。
ここではいざチームとして自動テストに取り組もうとなったときの私の失敗談をシェアさせていただきます。

## その1 失敗したときどうなるか考えていますか？
これは特に自動テストの組織を作ろうと思っているみなさんへ伝えたい話です。
もし今やっていること、もしくは今からやろうとしている自動テストが初めての取り組みなら、

**まず間違いなく失敗します。**

しかしそれは自動テストに限った話ではなく、障害なく組織を作れる方などごく一部の方だけでしょう。大なり小なり問題は発生し、解決のために時間を費やすことになります。
失敗はしてもいいんです。コケてみないとわからないこともあるでしょう。
問題は、**失敗しても大ゴケしない状態を作ってあげること**だと思っています。

### 小さく転ぶ大切さ

ここでまた私の例を出しましょう。
導入編でお話したプロジェクトに取り組んでいた同時期、私は複数のプロジェクトで自動テストの実装を行なっていました(今冷静に振り返ると、私はいろんなプロジェクトを掛け持ちしているから忙しい。完璧なアウトプットをするのは無理だ。という言い訳をするための逃げだったんだと思います)。
その一つに複数サービスの障害監視を自動テストで行うというものがありました。
弊社には障害を監視している組織があり、なにかサービスに問題が発生したときはエンジニアへ素早く連絡をする役目を担ってくれています。この業務の一部が手動でテストする流れになっていたため、ここを自動テストに置き換えて欲しいという依頼でした。
当時それなりに自動テストスクリプトを組んだ経験は積んでいましたが、まだ24時間365日稼働する自動テストの運用を行なった経験はない状態。まあなんとかなるだろうと自動テストのレポートツールと、自動テストが失敗した際にチャットツールへ通知するBotを作り、ちゃちゃっと2日ほどで10程度のサービスの死活監視のためのスクリプトを書き、実機を数台用意して運用を始めました。
このとき私は何を血迷ったか、早く実運用してほしいという要望を素直に受け止め、**ろくに試験運用もしないまますぐに本番運用を始めました**。

そして出るわ出るわエラーの山。

バックグラウンドで走らせたプログラムが異常終了を繰り返し、USBコネクションが不定期に断線し、最終的にMacがハングアップして動かなくなることなんてざらでした。
当然、対処できるのは私しかいません。
夜中だろうが休日だろうがBotから送られてくる異常終了メッセージと格闘する日々が続きました。
この時の一番の問題は、私が大変だったということではありません。
私の自動テストがエラーを出すたびに障害監視のチームは実機を確認し、手動でサービスに問題ないかも同時に確認し、さらに私に自動テストは問題ないかを確認するという作業が常に発生してしまったのです。これはおそらく相当な手間をかけていたことと思います。
つまり、自動テストで利益を得るどころか、**逆に仕事を増やす自体になってしまったわけです**。

導入前にしっかりとした試験期間を設けて問題を洗い出すこと、ただこれだけをやっていればよかっただけの話です。

もしあなたが上司なら、部下が小さくコケられる場所を作ってあげてください。
もし納期が〜予算が〜みたいな話になったら、部下を矢面に出さず、あなたが防波堤になってあげてください。
最終的にこれらの交渉や調整も部下本人がしないといけないでしょう。ただ、これが初めての自動テストへの取り組みなら、おそらくそんなこと考える余裕なんてないです。
もし部下が転んでしまったとしても、サービスへ影響が出ないように気を配りましょう。

## その2 周りの人たちを巻き込めていますか？
これは私自身の話ではなく、社内のあるプロジェクトの話です。
私がそのプロジェクトの自動テストに関する進捗を聞いたとき、議論はすべてQAチームの中に閉じてしまっていました。
このときの当事者の心情としてサービス開発者の手を煩わせたくない、テストに関することは自分らでなんとかしたいという気持ちが強かったようですが、時にそれはとてつもない**逆効果**になる可能性があります。

ここでは話をまとめるため、自動テストを実装していく人を便宜上

- QAの場合かつプログラム未経験の場合
- QAの場合かつプログラム経験者の場合
- サービス開発者

の3つのパターンに分けてお話しします。

### QAの場合
#### プログラム未経験の場合
おそらくサービス開発者の協力は必須になります。
加えて、つきっきりで教えてくれるメンターをぜひ見つけてください。

決して、**プログラムを書いたことないならやめとけ**という意味ではありません。ただし、実際に進めていく本人もその上司も、相当な覚悟を持っておいたほうが良いです。
**自動テストはプログラムが書ければそれでいい、という訳ではありません**。
プログラム(この場合は自動テストのスクリプト)はあくまで自動テストを実行するための手段のひとつに過ぎません。習得しないと仕事にならない知識や技術はそれ以外にも山のようにあります。
大げさに言うと、優れたテスト自動化エンジニアになろうと思ったら、多くの場合**サービス開発エンジニアに求められるもの**となんら変わりないスキルセットを要求されます。
**なにがわからないかがわからない**という状態から早く抜けるためにも、良い師匠を見つけることはとても大切なことになります。

また、特に未経験の場合**プログラムを学びたい**という目的にフォーカスを合わせてしまい、自動テストのスクリプトや関連するものを無理して**スクラッチから**書こうとする傾向があるように感じます。
それ、本当に一から書かないといけないですか？
OSSやテストベンダーが出しているサービスで代用できるものではないですか？
ぜひ一度今やっていることのROIを再確認してみてください。

上司の立場にある方へ言いたいことはこれだけです。
**やると決めたのであれば、教育コストを惜しむことだけは絶対にやめてください。**
未経験から始めるということは、ある程度軌道に乗るまで当然時間がかかります。
その間、プロジェクトとしてもその教育コストを払える、つまり、アウトプットが遅れたとしても育てるべきだという合意を取っておいたほうがいいかもしれません。取れないのであれば、上司自らつきっきりでサポートしてあげるくらいの覚悟が必要かもしれません。

#### プログラム経験者の場合
ある程度プログラミングやCS(Computer Science)、Unix系OSの基礎知識などがあることを前提で書きます。

この場合もサービス開発者の協力は必要です。最低限、取り組みに理解は得た方がいいです。
あなたがサービス開発に精通した知識を持っていて、完璧なプランを立て、予定通りのスケジュールで自動テストの実装・運用を行なっているのであればなにも言うことはありません。
しかし、ほとんどの場合そこまでうまくはいかないでしょう。

ググってもわからない技術的な問題にぶつかることもあるでしょうし、組織的な問題で仕事が進まないこともあるでしょう。
ときには使用しているOSSの不可解な挙動に悩まされ、Githubのissueを調べたり、ソースコードを確認しなければならないこともあります。
もともと1ヶ月でサンプルを作るはずが、**なぜか上手くいかない**よくわからないものに悩まされ、3ヶ月経ち、半年経ち。
このとき、QA組織に閉じたところだけで議論・進捗の共有が行われていたらどうなるか。
サービス開発者にはなにも情報が来ないので、QAチームはなにも言って来ないけど成果物っぽいものが見えて来ない。

こんな状態が続いたらどうなるか。
おそらく彼らは興味を失い始めます。最悪の場合**無関心**になってしまい、技術的な協力を取り付けることはおろか、自動テストをどうプロジェクトで活用していくかという議論すら難しくなってしまいます。ちょっと相談すれば解決する話になかなかたどり着けず、第三者から見たらとても非効率な方法を取らざるを得ない自体になりかねません。

もしあなたが上司で、自動テストに取り組んでいる部下がサービス開発の経験を持っていない場合、十分に注意してください。
導入編でも触れましたが、**自動テストの運用はサービスを作ることと同じくらい大変な作業です**。
先ほどの自動テストを行う目的に通じるものがありますが、あなたやあなたの部下が自動テストでやろうとしていることがプロジェクトにどんな良い影響を与えるのか。そのためにどんな協力をしてもらいたいのか。
ぜひpublicな場所で議論を行い、素直に協力を仰ぎましょう。

### サービス開発者の場合
自動テストを円滑に、硬く、スピーディーに実行しようと思ったらバックドアのAPIが必要になることもあるでしょうし、テストアイテムを作るためにDatabaseに直接アクセスしたくもなります。もしあなたが今のサービスのフロントエンドからバックエンドまでの全てに精通しているのであれば問題ないかもしれませんが、そうでない場合、同僚の協力は必要不可欠になります。
また、自動テストは継続的にメンテナンスをしないとすぐに腐ってしまいます。全ての自動テストを1人で管理するのは言うまでも無く困難で、理想的にはサービス開発者全員で実装・メンテナンスを行うのが理想です。
積極的に周りを巻き込んでいきましょう。

### ちなみに
この記事をレビューしてくれた同僚から、どうやってコスト削減の意識から抜け出せたのか？と、質問されました。
明確なターニングポイントがあったのか即答できなかったので相棒と当時を振り返ってみたところ、どうやら**外の世界を知った**という理由が大きく関係していそうです。
今の考え方が固まってくる前までは自動テストやソフトウェア開発の技術的な部分だけを追求していましたが、ミートアップへの参加やたくさんの書籍、記事に触れることで、今の自分に必要なのはもしかしたら技術だけではないのかもしれないと感じたのは覚えています。
余談ですが、私の考えを大きく変えた書籍の一つに[How google tests software](https://www.amazon.co.jp/dp/0321803027)があります。読んだことない方はぜひ一度読んでみてください。

# まとめ
誤解を恐れずに言うと、自動テストを作ってみたレベルで書くことは誰でもできます。
それこそプログラムに全く触れたことがない方でも根性とGoogleがあればなんとかなります。
ただし、それをプロジェクトへ利益を与えるほどの運用ができるかというと、**ほとんどの場合そこまで到達できずに消えていきます**。
私の過去の事例のように、それっぽい数字を見せることはできるかもしれませんが。

かくいう私も未だにもがき続けている途中です。
誇張ではなく、毎日どうやったらもっとプロジェクトの為になるか、どういうものがあったらうちの素敵な同僚たちがもっとサービス開発に集中できるか、そればかり考えています。
そして、自動テストをスクラッチから始めてそれなりの結果が出るまでには思ったよりも長い時間を要します。
孤独な戦いにならないよう、周りを巻き込む積極性も大事だと思います。

私が今のところこれだけの失敗を重ねながらも自動テストを一定の運用ができている要因は、**間違いなく素敵な同僚たちのおかげです**。彼らとあーでもないこーでもないとクソ真面目な議論をしながら仕事ができるおかげで、私は自分のしてきたことを客観的に振り返り、この失敗を糧によりプロジェクトへ貢献するためにはどうすればいいかを考え、日々成長させていただくことができたのだと思います。

私は数多くの失敗を経験させていただきました。
失敗させてもらってよかったと思うものが多いと思ういっぽうで、私の部下が経験したらと思うとゾッとするものもあります。
ただ、ここで語らせていただいた通り、**どうプロジェクトを良くしたいか**という目的さえしっかりしてれば多分大丈夫です。
みんな何もないところから始めているんです。もし失敗しても必ず軌道修正できます。

最後にもう一度だけ問います。

**あなたが自動テストを行う目的は何ですか？**

#### 余談
記事中で巻き込み事故のように失敗談を暴露された元上司に関して少し補足を。
今でこそ上司部下の関係ではなく、部署も別になってしまいましたが、今でもあーだこーだ本音で言い合える素敵な方です。当時もなにか衝突が発生したら建前抜きで本気で議論してくれたことをとても感謝しています。
この記事を書く際にも、「ありのまま全部書くよ？」という私の言葉に「もちろん！」と即答で返してくださいました。
この場を借りて感謝の言葉を。
ちなみに、私や同僚が開発した弊社内のテストシステムやテストライブラリには元上司の名前がprefixとしてついているものがたくさんあり、今日も元気に弊社のサービスをテストしてくれています。

あしたの最終日は[@policeman-khさん](https://qiita.com/policeman-kh)がJUnit関連かなんかを書くと言ってた気がします！どうぞお楽しみに！