「スライムが強かったらバグ」~テストと「品質」の関係について~

青山公士氏は、WEB+DB PRESS Vol.90の「国民的RPGオンライン化へのチャレンジ ドラゴンクエストⅩ開発ノウハウ大公開」で「ドラゴンクエストX オンライン」の開発プロセスについて述べる中で、品質管理について以下の様に述べています。

たとえばドラゴンクエストシリーズの序盤で対戦するモンスターのスライムが、まわりのモンスターより強いようなことがあればドラゴンクエストシリーズのお客様視点では異常です。仕様書に書いてあったとしても指摘すべきです。

WEB+DB PRESS Vol.90

WEB+DB PRESS Vol.90

もともとゲーム開発の分野では「デバッグ」と総称される、ソフトウェアテストの分野では探索的テストに分類されるテストがこれまで主流だったため*1、品質に対する考えも、業務アプリケーション開発やパッケージソフトウェア開発とは考えを異にするところがありますが、このような、品質管理が製品やサービスのあり方や、ユーザー経験に深くコミットメントする考え方がスクラムを始めとするアジャイル開発の現場では広まりつつあります。

スクラムガイドの「完成(Done)の定義」では、成果物としてのインクリメントが完成しているか及び、プロダクトを最終的にリリースするかの権限をどの主体に持たせるのかをフレームワークとして定義していませんが、プロダクトオーナーはプロダクトの価値の最大化に対して責任を負うものとされていますので、結果としてプロダクトオーナーがリリースの可否の判定に対して大きな役割を占めることになります。

ですが、プロダクトのライフサイクルの中でソフトウェアの規模が拡大する中で、個人としてのプロダクトオーナーがいつまでも品質に対して大きな権限を有したままで進むことはなく、筆者の経験の中では、品質保証を担うテストチームや開発エンジニアの中でのリードエンジニアなど、スクラムチームの中でリリースの可否、そして品質に対しての責任と役割を分担する方向に働いていきます。その中で、テストチームの品質に対する役割が、限定されたテスト仕様に基づいてアプリケーションの機能的な動作を確認する役割から、システムがどのようなユーザー経験と価値をもたらすかという点に徐々に拡大していきます。

プログラムの実行回数とテストの関係

ソフトウェア信頼性モデルに基づくソフトウェア信頼度成長モデルでは、横軸に時間をプロットしますが、プログラムはワインや発酵食品のように時間の経過とともに熟成するものではありませんから、この場合の時間とは、ソフトウェアテストの実施や、リリース後のフィールドでソフトウェアが使用される時間の経過の中で、プログラムが繰り返し実行されるにつれて発見された欠陥が除去され、それにより品質が向上していく、ということをさします。

すなわち、適切な開発プロセスの元では、プログラムが実行される回数と品質の成長度の間には関連がある、ということができます。

自動化されたユニットテストのメリットは、テストを実行する際のコストを手動でのテスト実行に比べて大きく削減することにより、単位時間当たりのテスト実行回数を多くすることができることにあります。開発者の環境上や、継続的インテグレーション(CI)環境上でのテストの実行回数を増やせることは、プログラムの実行回数を増やせることにつながりますから、そのことを通じて、自動化されたユニットテストを品質の向上に寄与させることができます。

エラーが自動でデリバリーされるのがDevOps?

継続的デリバリーの核心は、フィードバックのサイクルを素早く回すことにありますが、それはユニットテストカバレッジが十分になければ不可能です。

A/Bテスト、オートスケール、カナリヤテスト、Blue-Green Deploymentなど、DevOpsを推進する上での各種プラクティスは、いずれも、堅牢なコードベースの存在を前提としています。品質が安定していない状態でリリースサイクルを早く回してもバグが素早くデリバリーされるだけです。

サービス開発は、開発者だけで行うものでなく、プロダクトオーナー、QAエンジニア、インフラエンジニア、運用エンジニア、リモート開発チームなど、多数のステークホルダーが協調して行うものです。チーム相互の信頼をもたらすために必要なのは安定したプロダクトの品質であり、継続的インテグレーション(CI)を軸としたデリバリーのワークフローの確立のためには、自動化されたテストが足場として必要です。

OSが継続的にデリバリーされる時代の品質モデル

マイクロソフト社のWindows10では「Windows as a Service」というコンセプトに基づき、数年ごとにWindowsの新しいバージョンをデリバリーするリリースサイクルから、年に2~3回、小規模な機能更新が提供されるリリースサイクルが採用されました。*2Windows Insider Program*3に参加しているクライアントには、頻繁な場合は連日のようにWindowsのリリースブランチのビルドが提供されることがあり、いわばOSが継続的にデリバリーされる時代になったと言えます。

この章を執筆している時点*4でのWindows10の次期アップデートである「Creators Update」では高DPIのモニターに対応する「DPIスケーリング」に大きく改良が入っていますが、そのためInsider Previewのビルドでは、Visual Studio Code等一部のアプリでメニューが表示できなくなるという問題が一時発生しました。*5

これはOSの不具合ではあるのですが、アプリケーションのメニューが表示出来なくなるという不具合はユーザー経験に大きな影響を及ぼします。アプリケーション開発者やサービス事業者としては、Windowsの最新のビルドとの結合を頻繁に行い、アプリケーションまたはサービスへの影響を早い段階で特定する必要があります。

他方Google社の「Site Reliability Engineering」(SRE)の考えの根底には、

99%の信頼性を持つスマートフォンを使っているユーザーには、サービスの信頼性99.99% の場合と、99.999%の場合との違いは分からないのです。

というものがあります。自らが信頼性をコントロールできないハードウェア、ソフトウェアやネットワークの元で提供されるサービスの品質を考える上では、新しいユーザー価値をもたらす新しい技術を迅速に投入することと、安定したサービス運用の間で、サービスが提供不可能になるリスクをコントロールすることが必要になります。

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

平均故障間隔と平均復旧時間のトレードオフ

サム・ニューマン氏は、「マイクロサービスアーキテクチャ」の中で、平均故障間隔(MTBF:Mean Time Between Failures)と平均修復時間(MTTR:Mean Time To Repair)との間の最適化のトレードオフについて述べています。

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

欠陥を予め検出するための自動化された機能テストを増やすよりも、ブルーグリーンデプロイメントやカナリアリリースといった手法を用いて、本番環境に近い、もしくは本番環境内でのテスト手段を構築し、障害が発生した場合の修復時間を短くし、ユーザーへの影響を少なくするものです。

この際に留意すべきは、平均修復時間を短くするアプローチは、障害が発生した場合のユーザーへの影響を最小化することを念頭に置いているアプローチだと言うことで、デプロイされているコードベースに欠陥が内在していることを許容しているわけでもないし、堅牢でないコードベースを相手にバグとのいたちごっこをすることを指しているわけでもないということです。

あくまで、自動化されたユニットテストである程度のコードカバレッジが確保され、自動化されたエンドツーエンドのテストで機能のどの部分がカバーされているかが明確になっている時点で、さらにシステムの品質を向上させるための投資をどこに払うかということです。

魅力的品質と当たり前品質

継続的なサービス改善を目指す上で、品質というものが絶対的な指標でなくなった時、考慮すべき事は品質を向上することがどのようなユーザー経験の改善をもたらすかです。

狩野紀昭氏らは「魅力的品質と当たり前品質」*6の中で品質の構成要素について、充足されれば満足をあたえるが、不充足であってもしかたないと受け取られる「魅力的品質」と、充足されれば満足だが、不充足であれば不満を引き起こす従来の認識方法としての要素を「一元的品質」、充足されれば当たり前と受け取られるが、不充足であれば不満を引き起こす要素を「当たり前品質」と分類しています。

特に、最近増加してきたサービスの登録や基本的な機能の使用自体は無料であり、サービスを使用する中でのアイテム購入や追加機能に課金するサービスの形態や、使用できる機能にユーザーの登録コースごとに差異をつけているようなサービスの形態の場合、無料会員が受け取る便益が当たり前品質のベースを満たしているか、対価として支払うものとそれによって受け取る魅力的品質のバランスが取れているかは重要なポイントとなってきます。

その点において、ソフトウェア品質知識体系(SQuBok)が、

すなわち、品質とは顧客が認識した価値に対する顧客の評価である。

としたことは様々な示唆に富んでいます。

ソフトウェア品質知識体系ガイド -SQuBOK Guide-(第2版)

ソフトウェア品質知識体系ガイド -SQuBOK Guide-(第2版)

開発者のテストは品質に貢献するか

以上の話のまとめとなるのは、開発者が行うユニットテストを中心としたテストで、コンポーネントレベルの機能の確認が担保されていれば、魅力的品質を高めるだけのゆとりができるということです。また、Site Reliability Engineeringに代表される、機能の追加の迅速さと安定した運用のバランスをエンジニアリングとして作り込むプロセスにも、ユニットテストによるテスト群が揃っているかが、重要な要因となってきます。

サービスの規模が増大して行くにつれ、エンドツーエンドのテストや、ユーザーインターフェースを迂回してサービスのAPIを確認するテストなど、テストの階層をきめ細かくして対応していくことになりますが、その根底にはTDDによって作成されるユニットテストが基底に位置しています。

最後に

このエントリーは、ソフトウェアテスト Advent Calendar 2017 - Qiitaの12日目エントリーです。

記事本文は2017年4月に公開された技術書典2で頒布した「すいーとみゅーじっく vol.1 TDDってなんだ」から、「テストと品質」の章を、補筆の上CC BY-NC-SA 4.0のライセンス許諾のもと、公開するものです。初めての同人誌執筆で迫る入稿日とのプレッシャーの中書き上げた思い出深い草稿ですが、多くの人の元にこのエントリーが届けば幸いです。

fieldnotes.booth.pm