見出し画像

DevOpsバグフィルターでテストへの理解を深めよう

テストは大事と言われても全然ピンとこない……。テストの話をいくらしてもわかってもらえない……。その悩み、DevOpsバグフィルターで一挙解決!?

※この記事では、一部「バグ(虫)」を模したイラストおよび説明が用いられています。非常にわかりやすいモデルではありますが、お食事中にはご覧にならないことをお勧めします。

結論ファースト

この記事で何を語っているかを素早く知りたい、忙しい方のために、サマリーを載せておきます。しかし、おそらく一瞥しただけではまったく意味がわからないと思いますので、ぜひ本文もお読みくださればと存じます。

テストピラミッドはシンプルなモデルであり、広く使われてきたが、その反面、有効性に疑問を呈するテスターも存在する。Noah Sussmanのバグフィルターは、そんなテストピラミッドへの批判と再考の流れから生まれたものである。これをベースに、Katrina Clokieが改良・提唱するDevOpsバグフィルターは、各テストと運用を「粒度の異なるフィルター」および「サイズの異なる層」として捉えている。上から降りてくるバグが下に進むにつれ成長することで、対処が困難になっていく様子を表現しており、早期にバグを除去する重要性および各テストがカバーする範囲を視覚的に理解しやすい。テスターを含むあらゆるエンジニアが「テスト」への理解を深めることができる優れたモデルだ。

テストピラミッド

ソフトウェアテスト界隈にはいくつかのモデルがあります。有名なものとして、テストピラミッドがあります。

スクリーンショット 2021-07-16 9.43.41

図1:テストピラミッド(Test Automation Pyramid)

こちらは、Mike Cohnが2009年に書いた『Succeeding with Agile』(Addison-Wesley、2021年7月現在未邦訳)の第16章に記載された図で、Unit・Service・UIの各自動テストの構成を表したものです。下層のUnitテストを多く、上層のUIテストを少なくしようということが表現されています。

ちなみにこの図は、原著ではThe Test Automation Pyramidという名称で示されています。よって、本来ならテスト自動化ピラミッドと呼ぶべきかもしれませんが、本稿では一般的な呼称であるテストピラミッドという表記を採用します。

テストピラミッドは優れたメタファーとして広く親しまれてきました。また、派生系として、アンチパターンを示すアイスクリーム・コーンというモデルも登場しています。

画像2

図2:アイスクリーム・コーン(Ice-cream Cone Anti-Pattern)

アイスクリーム・コーンでは、テストピラミッドとは異なり、Unit Tests(単体テスト)が少なく、Automated e2e Tests(E2E自動テスト)が多くなっていて、その上にさらに多くのManual Regression Testing(手動で実施される回帰テスト)が載っています。

進む「テストピラミッド批判」

ところが近年、テストピラミッドを批判・再考する動きが出てきています。Seb Roseは次のように書いています。

The Test Pyramid is a metaphor intended to suggest that the foundation of a test automation strategy should be large numbers of small, fast unit tests. As the automated tests become larger and slower, there should be fewer of them. That’s it. Period.
(Seb Rose (2020) "Eviscerating the Test Automation Pyramid")

訳:テストピラミッドというメタファーが提唱しているのは、たくさんの軽量かつ高速な単体テストがテスト自動化戦略の基礎にあるべきだ、ということだ。自動テストが大きく、遅くなっていくにつれて、減らしていくべきだ、といっている。それだけのこと。おしまい。

いかがでしょう。「テストピラミッドなんて、別に大したことは言ってないんだよ!」という、なかなか、挑戦的な文章だと思いませんか。あるいは「私も同じことを思っていたよ!」という方もいらっしゃるかもしれませんね。

もう少し穏当な文章として、Ham Vockeが書いた次の記事もご紹介しましょう。

Unfortunately the concept of the test pyramid falls a little short if you take a closer look. Some argue that either the naming or some conceptual aspects of Mike Cohn's test pyramid are not ideal, and I have to agree. From a modern point of view the test pyramid seems overly simplistic and can therefore be misleading.
(Ham Vocke (2018) "The Practical Test Pyramid")

訳:残念ながら、テストピラミッドのコンセプトは、よく見てみると少し物足りない。Mike Cohnのテストピラミッドのネーミングや概念的な部分が理想的ではないという意見があるが、同意せざるを得ない。現代的な視点から見ると、テストピラミッドは極端に単純化されているようで、そのせいで誤解を招きかねない

統計の世界では、George P. E. Boxが言ったとされる「すべてのモデルは誤っているが、使えるものもある(All models are wrong, but some are useful.)」という格言があります。現実を完璧に反映しないかぎりどんなモデルも「誤っている」わけですが、テストピラミッドは特に、単純化されすぎて人によって解釈が異なる結果、誤解を招いてしまっているのではないかと批判されているのです。

Noah Sussmanのバグフィルター

こうした「テストピラミッド批判」の流れを受けて、新しいモデルを考える動きが活発になりました。Noah Sussmanが描いて公開したのが、次の図です。

スクリーンショット 2021-07-16 8.54.18

図3:バグフィルター(The Test Pyramid Re-Imagined as a Bug Filter)

Noah Sussmanのアイデアは、テストピラミッドをひっくり返したモデルを使い、上から降ってくるバグを単体テスト・結合テスト・E2Eテストというフィルターでキャッチするものです。上層のテストで抽出できないバグを下層で捉え、最も微細なバグだけがE2Eテストまでのフィルターをすり抜けるといいます。

一定、納得感のある説明がなされていると思われます。しかし、発見されうるあらゆるバグが単体テストのスコープに収まるかというと、やや慎重に考えた方がよさそうな気がします。

テスターの皆さんの中には、本番環境で発生しているバグが、検証環境ではどうしても再現しない……という経験をお持ちの方もいらっしゃると思いますが、環境依存のバグも単体テストで見つかるものでしょうか。本番環境と非常に近い状態の検証環境・開発環境でテストをしていたら、なるほど、確かに見つかりそうな気がしてきますが「そんな理想的な環境は用意できないから、あまり現実的な話ではない」と感じる方もいらっしゃるかもしれませんね。

他にも、モバイルアプリ開発では多くの機種では発生しないのに、特定の端末でのみ発見されるバグがあります。そんなバグまで単体テストで完全に検知できるかというと……ちょっと難しいのではないでしょうか。

Katrina ClokieのDevOpsバグフィルター

Noah Sussmanのモデルを進化させ、DevOpsでの自動テストをイメージして構築された「DevOpsバグフィルター(DevOps Bug Filter)」を生み出したのが、Katrina Clokieです。これは、2017年に発行された書籍『A Practical Guide to Testing in DevOps』(LeanPub、2021年7月現在未邦訳)で紹介されています。

スクリーンショット 2021-07-16 7.03.37

図4:DevOpsバグフィルター(DevOps Bug Filter)

このモデルでは、従来のバグフィルターで想定されていた3種類のテスト(Unit・Integration・End to End)のほかに、下段にAlerting(アラート)・Monitoring(モニタリング)・Logging(ログという3層が追加されています(モニタリングだけ日本語でも-ing形なのは、一般的に知られている表現を優先して訳しているためです)。これらの3層は、本番環境での活動を示しています。一方、上段の3層はいずれもテストですから、もちろん開発・検証環境での活動ですね。DevOpsでは開発と運用を切り離して考えるべきではないということから、このように本番環境を併せて考慮したデザインになっているのです。

ここでは、上段という言葉でUnit(単体テスト)・Integration(統合テスト)・End to End(E2Eテスト)の3つの層を、下段という言葉でAlerting(アラート)・Monitoring(モニタリング)・Logging(ログ)の3つの層を表現することにしましょう。

フィルターの粒度

それぞれの層が持つフィルターは、それぞれ細かさ(粒度)が異なります。すなわち、上段の3層では、上から下へ荒くなっていきます。最上層にある単体テストが最も細かいフィルターを持ち、統合テストが中程度の荒さ、E2Eテストのフィルターはさらに荒いものとなっています。下段のアラート・モニタリング・ログでは、逆に下の層に行くほど粒度が細かくなっていきます。アラートが最も荒い粒度で、モニタリングはそれよりは細かく、ログは最も細かいフィルターを持つのです。

フィルターの細かさは、大まかに、図の色でも表現されています。最上層の単体テストと最下層のログが同じ色で描かれていることに着目してみてください。

DevOpsバグフィルターでバグはどう表現されるか

オリジナルのバグフィルターと同じく、バグは上から降ってくる形で表現されています。また、その名の通り虫を模したイメージで、次のような図で表現されています。

スクリーンショット 2021-07-16 7.22.09

図5:DevOpsバグフィルターとバグのイメージ

紫色で追加されているのがバグです。最上層の単体テストを見てみると、丸いものがいくつか引っかかっているように見えますね。これはバグの卵です。単体テストは細かいフィルターを備えているので、問題が大きくなる前の、すなわち卵の状態のバグを捉えることができるのです。単体テストで見つけたバグの除去にかかる時間と手間は、小さくて済みます。

次の層に移ると、やはりバグがキャッチされていますが、今度は孵化して幼虫になっています。バグは、発見が後になればなるほど、除去するために多大な人的・時間的コストがかかります。このモデルでは、それを虫が成長していく様子で表現しているというわけです。E2Eテストや本番環境のアラートで見つかるバグなんて、羽化しちゃっています。あぁ、嫌だ嫌だ……(虫嫌い)。

「では、すべてのバグを卵の状態で捉えればいいじゃないか」と考える方もいらっしゃるかもしれません。しかし、Noah Sussmanのバグフィルターをご紹介したときに考えたように、プロダクトのすべてのバグを単体テストで除去するなんてことはできません。

そのことを「層のサイズ」で表現したのが、DevOpsバグフィルターのもう一つの工夫なのです。

層のサイズ

DevOpsバグフィルターで改良されているもうひとつの点が、それぞれの層のサイズが異なっていることです。これは、テスト実施に伴って利用する環境や連携するシステムの多さを反映しているためです。単純な話ですが、利用する環境や連携するシステムが多くなればなるほど、新たにバグが増える可能性は高まります。

最も上層にある単体テストは、多くの場合、開発者が自身のマシンで構築している開発環境で行い、連携部分はモックやスタブなどを利用するため、環境からの影響を最も受けにくいテストです。

一方で、その下の層である統合テストとなると、たとえばシステム間でAPI連携を行ったり、DBアクセスが生じたりするでしょう。そこで、単体テストよりもサイズが広く取られることで、単体テストでは検知できない性質のバグが統合テストでキャッチされるのだと、このモデルでは示唆されているのです。言い換えると「いくら単体テストのカバレッジを上げようと、検知できないバグがある」ということです。

さらにもう一層下にあるE2Eテストとなると、連携するシステムはさらに広くなり、ほぼ本番環境と遜色ない状態でのテストを実施することになるでしょう。そこでは上層のテストでは捉えきれないバグが見つかる可能性があります。E2Eテストでボロボロとバグが見つかるようでは困りますが、E2Eテストでないと見つからないバグがある、ということでもあります。同じことは本番環境でも言えます。

DevOpsバグフィルターの下の段は、本番環境を表しています。よって、層のサイズはこれ以上広くなりません。アラートを用意しておくことで、本番環境で発生したバグを速やかに見つけることにつながります。しかし、アラートは荒いフィルターですので、バグを見逃したり、原因分析まで至らない可能性が大いにあります。

そこで次の層であるモニタリングの出番です。モニタリングはアラートよりは手間がかかりますが、よりバグを検知しやすいでしょう。ただ、モニタリングはユーザーの操作をベースにしたものですから、プログラムのどの行が原因なのかを正確につかむことは難しいかもしれません。

そこで最後に出てくる最も細かいフィルターがログです。不具合分析の時は、まずログを読めと教わった若かりし日を思い出しますが、DevOpsでもログは強力な武器なのです。ただし、運用中のシステムであることを考えると、膨大な量のログと格闘しなければならないであろうことは、容易に想像できるでしょう。

もしも、フィルターが破れていたら……

ここまでの理論は、あくまでもそれぞれの層で完璧に近い形でフィルターが用意されていれば、という前提のもとで展開されてきました。単体テストで表現すればC2カバレッジ100%を達成している状態とでも表現できるかもしれません。

しかし、冷静に考えてみましょう。そんな会社ばかりではありませんよね。というわけで、もしテストが不十分だとどういう状況になるかを示した図が、こちらです。

スクリーンショット 2021-07-16 8.06.04

図6:不完全なフィルターと増えたバグ

バグが増えていますね! 最上層の単体テストを見ると、フィルターが荒くなっていて、テストが十分に行われていないとわかります。これは単体テストでキャッチされるべき卵の状態のバグが捉えられずに、下層で孵化・羽化しているのです。E2Eテストで見つけたバグの中に「単体テストで見つけるべきだったバグ」が紛れてくることが(残念ながら)よくあって、バグの除去と再テストに時間がかかるわけですが、この図が示しているのはそのような状態です。

バグがまだ卵の状態で見つかっていたら、非常に少ないコストで除去できたのに、E2Eテストや、まして本番環境で見つかったら、非常に高いものにつきます。本番環境でサービスが停止したなんてことになったら……いやぁ、考えたくもありませんね。

本番環境でのみ発生するバグは、確かにあります。しかし、だからといってそれ以前の層でのテストを疎かにしていいということにはなりません。むしろ、本番環境で起こる想定外のバグにいち早く対処するためにも、自分たちがリリースする機能の品質はできるだけ万全にしておきたいと考えるならば、日頃からテストを書き、また自動化を進める機運が高まっていく……そんな文化を醸成する開発組織が増えることを願っています。

ご紹介したKatrina ClokieのDevOpsバグフィルターは、まだあまり知られていませんが、視覚的にたいへんわかりやすく、テストをこれから学ぶ人にとっても、テストのことをよく知っている人にとっても、学びと発見があるモデルです。

ぜひ、皆さんの職場でも活用してみてください!

出典元の『A Practical Guide to Testing in DevOps』は電子書籍で発売されていますので、ご興味のある方はご一読ください。

結論ラスト

冒頭に掲載したものと同じサマリーを載せますので、ぜひ目を通してみてください。

テストピラミッドはシンプルなモデルであり、広く使われてきたが、その反面、有効性に疑問を呈するテスターも存在する。Noah Sussmanのバグフィルターは、そんなテストピラミッドへの批判と再考の流れから生まれたものである。これをベースに、Katrina Clokieが改良・提唱するDevOpsバグフィルターは、各テストと運用を「粒度の異なるフィルター」および「サイズの異なる層」として捉えている。上から降りてくるバグが下に進むにつれ成長することで、対処が困難になっていく様子を表現しており、早期にバグを除去する重要性および各テストがカバーする範囲を視覚的に理解しやすい。テスターを含むあらゆるエンジニアが「テスト」への理解を深めることができる優れたモデルだ。

お読みになって、もし「なるほど、わかった!」と思えたなら、この記事は役割を果たせたということになるでしょう。

エンジニア・デザイナー・PdMを積極採用中!

「働きがいのある会社ランキング」で8年連続上位選出されている教育事業会社・グロービスでは、EdTech事業の強化とグローバルビジネスの本格展開に伴い、QAエンジニアやテストエンジニア、また各開発エンジニア・デザイナー・プロダクトマネージャーの採用を強化しています! まずはカジュアル面談にいらっしゃいませんか? ご興味のある方は、こちらの記事を書いた@mkwrd までお気軽にどうぞ!

この記事が気に入ったらサポートをしてみませんか?