IT Testing & Quality Assurance
ソフトウェアテストは、その歴史のほとんどにおいて、引き算の作業として組み立てられてきました。まずシステムを構築し、リリース前に欠陥を取り除くという考え方です。この枠組みこそが、防ぐ手立てがいくらでもあったはずの本番障害に組織が繰り返し驚かされる、最大の理由です。品質はパイプラインの末尾で製品に検査を通して組み込むものではありません。品質はシステムそのものの性質であり、それを生み出すプロセスの性質であって、最初の設計判断の時点から存在するか、あるいは欠けているかのいずれかです。本稿では、テストと品質保証をゲートとしてではなく、一つのエンジニアリングの規律として扱い、この分野がうまく機能するときにどのように機能し、失敗するときにどこで失敗するのかを論じます。
品質はフェーズではなく性質である
この主題が、十年前よりも今こそ重要である理由は、ソフトウェアのコスト構造が反転したからです。多くの組織でリリース頻度は四半期ごとから日次あるいは時間単位へと移り、依存関係は増殖し、システムはますます記述されるのではなく組み立てられるようになりました。どの単一チームもその挙動を完全には制御できないサービス、ライブラリ、サードパーティのプラットフォームから構成されるのです。そうした環境では、検証を末尾の独立したフェーズに集中させるテストモデルは、単純にペースについていけません。予定されたリリースの前に別の品質チームがすべてを捕捉するという心地よい猶予はもはや存在しません。旧来の意味での予定されたリリースそのものが存在しないからです。
品質がシステムの性質であると言うとき、私たちは正確な意味を込めています。システムが品質を備えているとは、それが直面するさまざまな条件のもとで、実際の挙動が意図された挙動とどの程度一致するか、そしてその一致がどの程度安価かつ繰り返し実証できるか、という度合いを指します。この両面がともに重要です。たまたま正しく動作するものの、英雄的な手作業なしにはそれを示せないシステムは、エンジニアリングの観点では高品質なシステムではありません。それは正しさを検証できず、したがって次の変更の際には信頼できない、脆弱なシステムです。
この捉え直しには、リーダーがしばしば抵抗する実践的な帰結があります。品質が性質であるならば、それは設計され構築されるものであって、後から付け足すものではありません。テスト容易性を最も大きく左右する判断は、いかなるテストが書かれるよりもはるか以前に下されます。コンポーネントをどう区切るか、状態をどう管理するか、副作用をどう分離するか、挙動を安定したインターフェースを通じて公開するか、それとも表示と絡み合わせるか、といった判断です。テストを他人の後回しの問題として扱うチームは、こうした選択肢を自ら閉ざし、そして手遅れになってから、システムがあらゆる面で検証を拒むことに気づきます。この分野の現状は、フェーズモデルから離れ、品質を提供組織全体にわたる本質的かつ継続的な関心事として扱う方向への、緩慢で不均一な移行として理解するのが最も適切です。
第一原理とピラミッドの形
テスト戦略とはテストの一覧ではありません。それは、検証の労力をどこに、どの粒度で、どのリスクに対して費やすかについての、意図的な判断の集合です。出発点は、異なるテストが答える問いを区別することです。単体テストは、小さなロジックの一片が作者の意図どおりに単独で振る舞うかどうかに答えます。統合テストは、コンポーネント同士がそれらの間の契約について合意しているかどうかに答えます。エンドツーエンドテストは、組み上がったシステム全体にわたって、完結したユーザージャーニーが機能するかどうかに答えます。これらは互換ではありません。それぞれが、他では構造的に捕捉できない種類の欠陥を捕らえ、それぞれが実行時間、保守負担、そして失敗したときの診断の明瞭さにおいて異なるコストを負います。
テストピラミッドは、これらをどう均衡させるかを表現した古典であり、その論理は美的というより経済的です。基部に近いテストは数が多く、高速で、精密です。単体テストが失敗すれば、たいていは問題の行を直接指し示します。頂点に近いテストは数が少なく、低速で、広範です。エンドツーエンドテストが失敗すると、長い連鎖のどこかに何か不具合があると教えてくれますが、それは価値がある一方で診断には費用がかかります。したがって健全な戦略は、その問いに真に答えられる最も安価なレベルへと検証を押し下げます。単体テストならミリ秒で確定できる日付書式のルールを確かめるために、ブラウザのジャーニー全体を走らせたりはしません。
ピラミッドは、チームが認めるよりも頻繁に、実務では反転してアイスクリームコーンになります。薄い単体テストの基部、膨れ上がった低速なエンドツーエンドテストの層、その上にちらほら乗る手作業のチェックです。この形は問題の兆候です。それはたいてい、根底のコードが単独ではテストしにくかったために、チームがすべてを最も外側のインターフェースを通じてテストすることで埋め合わせたことを意味します。そこではあらゆるチェックが低速で、不安定で、些末な詳細に結びついています。ピラミッドが本当に伝えているのは、暗記すべき固定比率ではなく、一つの原則です。すなわち、リスクを有意に減らせる最小かつ最速のテストを選び、頂点の重さは受け入れるべきテスト様式ではなく、直すべき設計上の問題の証拠として扱え、ということです。
この分野が向かう先
現代の実践における最も重大な転換は、シフトレフトという言葉に集約されます。これは検証を作業の流れのより早い段階へ、変更が出荷される瞬間ではなく、変更が構想される瞬間の方へと移すことを意味します。その浅い形では、これは単にパイプラインでより多くのテストを走らせることにすぎません。真剣な形では、さらに左へと踏み込みます。一行が書かれる前に受け入れ基準を明確にし、その基準を実行可能なチェックとして表現し、テスト容易性の観点から設計を第一級の関心事としてレビューするのです。その経済的な論拠は十分に確立されています。要求がまだ一つの文であるうちに捕らえた欠陥を直すコストはほぼゼロですが、同じ欠陥が本番で発見されると、コストは桁違いに大きくなり、ときには金銭では取り戻せない信頼を失います。
継続的テストは、これを提供パイプラインそのものへと拡張します。あらゆる変更が自動検証スイートを起動し、その結果が進行を制御するのです。ここでの規律は、単にテストを持つことではなく、開発者が実際にその完了を待ち、それを信じられるほど高速で信頼に足るスイートを持つことです。一時間かかり、五回に一回はランダムに失敗するパイプラインは、パイプラインがない方がましです。それは人々に赤信号を無視するよう仕込むからです。これと並んで、契約テストが、システム全体を立ち上げることなくサービス間の合意を検証する手法として成熟しました。各側が共有インターフェースを守っていることを確認できるのです。これは、多数の小さなサービスの上に築かれた組織にとって、過去十年で最も真に有用な発想の一つです。
さらに二つの潮流が、率直な扱いに値します。リスクベースドテストは俗説から方法論へと進みました。一律のカバレッジを追うのではなく、チームは発生可能性と影響の積が最も高いところに意図的に労力を集中させ、賭け金が低いところでは検証を薄くすることを意識的に受け入れます。一方で探索的テストは、当てのないクリックではなく、熟練した規律として再評価されました。有能な探索的テスターは、システムがどのように失敗しうるかについて仮説を立て、それを体系的に探ります。誰かがすでに確かめようと考えたことしか確かめないスクリプト化されたテストでは決して明らかにならない欠陥を見つけるのです。テストケースやデータを起草する生成ツールが近年登場したことは現実的で有用ですが、それはこうした判断を置き換えるのではなく増幅します。機械は千のチェックを提案できますが、そのどの千が実行に値したかを決めるのは人間の推論だけです。
実際にテストできるシステムを設計する
元が取れる自動化とは、より多くのテストを書くことではありません。それは、テストの継続的なコストが、それが防ぐ欠陥のコストを下回るように、システムとスイートを設計することです。ここでアーキテクチャと品質が交わります。テスト容易性は設計上の性質であり、コードをテスト可能にするのと同じ特性、すなわち明確な境界、明示的な依存関係、分離された副作用、決定的な挙動は、他のあらゆる理由においてもコードを保守しやすくする傾向があります。テストが苦痛であるとき、その苦痛はたいてい診断的です。それは設計に隠れた結合や曖昧な責務があると告げているのであり、直すべき対象はコードであって、ますます手の込んだテストの足場ではありません。
経済性は、チームがめったに測らない二つの量に左右されます。テストを生涯にわたって書き保守するコストと、それが捕らえる失敗の価値です。真に誤りを起こしやすいロジックを守る、高速で焦点の絞られた単体テストは、優れた見返りを持ちます。ボタンが動くたびに壊れ、絶えず手入れを要し、たいていは下位でもすでにカバーされているロジックを再確認するだけの脆いエンドツーエンドテストは、負の見返りを持ちます。そして静かにエンジニアリングの時間を食いつぶすことこそ、ほとんどの自動化の取り組みが息絶える道筋です。規律とは、挙動に敏感で構造には鈍感なテストを書くことです。そうすればシステムが誤ったことをしたときに失敗し、別のやり方で正しいことをしたときには沈黙します。
そしてここでカバレッジ、この分野で最も誤解されている数値に話が及びます。コードカバレッジは、テストの実行中にどの行や分岐が実行されたかを測ります。測るのはそれだけです。高いカバレッジは、テストがコードに触れたことを教えてくれますが、何が起きたかについて意味のある表明をしたかどうか、その動かしたケースが重要なものであるかどうか、合否を判定するオラクルが正しいかどうかについては何も語りません。結果を確かめずにコードを実行するだけのテストで、ロジックが壊れていても合格するようなテストで、九十パーセントのカバレッジに達することは十分に可能です。カバレッジは下限として、またどのテストも一度も走らせていないコードを見つける手立てとして有用であり、それは知る価値があります。しかし目標としては危険です。それが目標になると、人々はリスクではなく指標を最適化し、確信を高めることなく数字を高める、浅いテストを書くようになるからです。カバレッジはどこを見ていないかを教えてくれますが、見たものが正しいと教えてくれることは決してありません。
テストはどこで誤るか
テストにおける失敗は、組織を越えて見覚えのある形で繰り返される傾向があり、それらに名前を与えることは、チームが自らの状況を明確に見る助けになります。
反転したピラミッド。薄い単体テストの基部と、低速なエンドツーエンドのチェックへの重い依存であり、たいていはコードが最初から単独でテストできるように設計されていなかった症状です。スイートは低速で信頼できなくなり、開発者はそれを信じなくなり、締め切りの圧力のもとで検証は静かに手作業へと逆戻りします。
不安定なテスト。コードに何の変更もないのに合格したり失敗したりするテストで、その多くはタイミングの前提、共有された状態、あるいは環境への隠れた依存が原因です。不安定さは、その見かけの大きさに不釣り合いなほど腐食的です。狼が来たと叫ぶスイートは誰もが赤信号を無視するよう仕込み、一つの見過ごされた失敗こそ、緑のパイプラインを通じて本物の欠陥が本番に届く経路だからです。
見せかけのカバレッジ。カバレッジの割合を品質の定義として扱うことであり、欠陥を捕らえるためではなく行を実行するために書かれたテストを生み出します。数字は上がり、確信は上がらず、そうでないと信じ込むことで組織はかえって悪くなります。
事後のテスト。設計が凍結されてから検証を後付けすることで、欠陥を防ぐ安価な機会はすでに過ぎ去っています。残るのは、より早い明確さがあれば完全に防げたはずの問題を、高いコストで検出することです。
品質のサイロ。品質に対するすべての責任を、流れの末尾に置かれた別チームに委ねることです。これは欠陥を生み出す人々を、それをやめる助けとなるフィードバックから切り離し、すべてをボトルネックのスループットまで減速させ、品質を共有された基準ではなく交渉事に変えてしまいます。これらの失敗モードのいずれにおいても、処方箋がより多くのテストであることはめったにありません。それは、より適切に配置されたテスト、正直な指標、より早い関与、そして検証を拒まない設計です。
Nashuaのテストと品質保証への取り組み方
Nashuaは品質を、リリース前に差し込む検査ステップとしてではなく、提供システム全体のエンジニアリング上の性質として捉えます。クライアントとの取り組みは、検証の労力が現在どこに置かれているか、それが実際にどのリスクに対処しているか、そして意図された挙動と実証された挙動の間の隔たりがどこにあるかについての、曇りのない評価から始まります。私たちは、既存のテストスイートの形、パイプラインの速度と信頼性、品質に関する判断が下される地点、そして開発者をフィードバックに結びつけるか、あるいはそこから隔離するかのいずれかを担う組織構造を見ます。その成果物は、汎用的な成熟度スコアではなく、現在のやり方がどこで労力をうまく費やし、どこで誤ったリスクに対して費やしているかについての、具体的な描像です。
そこから私たちはクライアントのチームとともに、儀式ではなくリスクに根ざしたテスト戦略を築きます。それは、各問いに答えられる最も安価なレベルへと検証を押し下げること、反転したところでは健全なピラミッドを回復させること、そして低速で広範なチェックを真に必要とするごく少数のエンドツーエンドのジャーニーについて意図的であることを意味します。私たちはテスト容易性を設計上の関心事として扱うため、私たちの関与はテストスイートで止まらず、アーキテクチャやインターフェースの判断にまで及びます。私たちはチームがシフトレフトの実践をその真剣な形で採り入れるのを助け、実装の前に受け入れ基準を明確にし、それを実行可能なチェックとして表現し、そして人々が実際に頼るほど高速で信頼に足る継続的テストのパイプラインを構築します。
決定的に重要なのは、私たちが自動化を、それ自体を目的とするのではなく、正当化されるべき投資として扱うことです。私たちはチームが、十年にわたって保守する価値のあるテストと、静かにエンジニアリングの時間を消耗させているテストとを見分けるのを助け、指標については率直です。カバレッジは診断上の下限であって決して目標ではなく、リスクの低減こそがスイートの真の価値の尺度です。探索的テストと手作業のテストは、自動化が提起できない問いのための熟練した規律として、その居場所を保ちます。その結果は、完成した作業とその利用者の間に立ちはだかるフェーズではなく、ソフトウェアの設計と提供のあり方に組み込まれた、チーム全体が所有する品質の実践です。
Nashuaが違いを生む場所
Nashuaがもたらす違いは、より大きなテストスイートではなく、品質がどこから生まれるかについてのより健全な判断力です。多くの組織はテストを書けますが、どのテストがその働きに見合っているか、どこで労力が積み上がる一方でどのリスクがカバーされないまま残されているか、そしてどのアーキテクチャ上の判断がシステム全体を静かに検証しにくくしているかを言い当てられる組織は、はるかに少ないのです。数多くのエンタープライズシステムにわたる長年の実践から築かれたその判断力こそが、テストをコストセンターから持続的な確信の源へと変えるものであり、それこそ私たちが、リリース前の最後のレビューではなく、最初の設計の対話から発揮するものです。
さらに、作業が前提としてよいことを変える実践的な帰結があります。ある取り組みが、まだ存在しない機能を必要とするとき、それは調達サイクルやベンダーのロードマップを待つ必要がありません。enterprise platformは、エージェンティック・エンジニアリングを通じて、ほとんどあらゆる機能を迅速に受け入れられるように作られています。必要なものを平易な言葉で記述すれば素早く生成されますが、それは常に確固たるアーキテクチャ原則の内側で、そして厳格な品質保証のもとで行われるため、速度が一貫性、セキュリティ、統制を犠牲にすることは決してありません。その効果は単に便利であるにとどまらず、戦略的です。それは自製か購入かの境界線を動かし、選択肢を安価に保ち、戦略が棚にたまたまあったものに合わせて曲げられるのではなく、アーキテクチャが戦略に従うようにします。
これらを結びつけているのは、品質を、それを備えるシステムから切り離せるものとして扱うことへの拒絶です。私たちは検証を設計、提供、運用に組み込み、意図された挙動と実際の挙動の一致を安価かつ継続的に実証できるようにし、組織が、防ぐ手立てをすべて持っていた失敗にもはや驚かされないようにします。ソフトウェアが、それを信頼できる能力よりも速く成長してしまったエンタープライズにとって、末尾で品質を検査して組み込むことから、最初から品質を作り込むことへのその転換こそ、真に永続する違いが生まれる場所です。
