はじめに

最近、システム障害によるサービスの一時停止や、システムの不具合を利用したサイバー攻撃による個人情報の流出等、システムの欠陥に起因する様々なトラブルを耳にする機会が多くなりました。日々ITシステムの管理や導入をされている方にとっては、これらのニュースは決して他人事ではないと思います。
このようなシステムの不具合によるトラブルは、システムのリリース前、ないしは機能改修時において、適切な検証・テストを実施することで、未然に防ぐことが重要です。今回は、テストの基本的な考え方とソフトウェアテストの7原則についてご説明します。

テストの4つの品質特性

現代社会では、経済活動や日常生活のほぼ全てにコンピュータシステムが活用されており、人が作ったOSやアプリケーションなどのソフトウェアによって管理および制御され、当たり前のように日々ユーザーにサービスが提供されています。
しかし、これらのシステムを”正しく”動作させるということは、実はとても難しいことです。
システムを”正しく”動作させるためには、下記の4つの品質特性で正常性を担保する必要があります。

  • 利便性(快適に)
  • 可用性(止まらずに、遅くならず)
  • 正確性(エラーがないように)
  • 安全性(安全に)

システムは、多くの場合、ハードウェア、OS、ミドルウェア、アプリケーションが層として構成されており、これらが相互に連携して動作しているため、全ての層の、全てのコンポーネントにおいて、上記の要件を満たしていることを担保することは非常に難しく、とりわけ、近年のアプリケーションは、基本的にLANやインターネットを介したネットワーク通信を必要とするものがほとんどであるため、ブラウザのようなユーザーエージェントや、クライアントアプリケーションとの接続性も意識しなければならず、そのシステムの動作の”正しさ”を保証することは年々難しくなっています。

テストの重要性

ほぼ全てのソフトウェアは、開発者が業務要件を満たすためのビジネスロジックや業務フローを分析し、それをプログラムで表現していくことによって実装されています。
しかし、開発者も人間であるため、時にミスを起こすことがあります。
そして、これらのミスは、実装上の不備や、ドキュメントの欠陥として顕在化し、しばしば故障の原因となり、結果として様々な損害が発生することがあります。

システムの欠陥による損害の具体的事例

このようなリスクを回避するため、プロダクト開発者やサービス提供者は、サービスのリリース前、または機能改修時において、ソフトウェアが仕様書通りの挙動となっているかをチェックし、システムに欠陥がないことを確認する“テスト”を行う必要があります。
ソースコードやインフラ、ドキュメントを厳しくテストし、システムが稼動する前に欠陥を摘出して修正することが出来れば、実行環境において予期せぬ障害が発生するリスクを低減でき、結果としてプロダクトの品質を最低限保障することができます。

テストの目的

JSTQBではテストの目的を定義していますが項目が多くあり、少し冗長化していますので、以下4つに要約しています。

  • 故障や欠陥を発見する
     (テストの最優先目的であり、リスクを軽減する活動)
  • 品質に対する信頼を積み重ねて、所定のレベルにあることを確証する。
     (検証妥当性確認の成果物を評価して品質を確証する)
  • 欠陥の作りこみを防ぐ
     (テストで検出された欠陥や故障の原因を分析して再発防止に役立てる)
  • 意志決定のための情報を示す
     (上記を纏めてステークホルダーの意思決定を支援します)

テストの重要性は理解しているが、時間およびコスト的な制約もある中で、どのような考え方やアプローチで、テストを計画・実行してよいかわからないという方も多数いらっしゃると思います。
そこで、より効率的かつ有効なテストの実行に役立つかもしれない「ソフトウェアテストの7原則」をご紹介します。すでにご存知の方もいらっしゃるかもしれませんが、この7原則は、世界共通の一般的なガイドラインとなっており、ソフトウェアテストの50年以上の歴史の中で培われてきた、いわば先人の知恵の集積といえます。

ソフトウェアテストの7原則 ~ISTQB:Seven Testing Principles~

原則 1: テストは欠陥があることは示せるが、欠陥がないことは示せない
~ISTQB:Testing shows the presence of defects, not their absence~

テストにより、欠陥があることは示せるが、欠陥がないことは証明できない。テストにより、ソフトウェアに残る未検出欠陥の数を減らせるが、欠陥が見つからないとしても、正しさの証明とはならない。

JSTQBより引用

[概要説明]
構造化プログラミングの提唱者であり、コンピュータ科学者であるダイクストラ(Edsger Wybe Dijkstra)は、ソフトウェアテストにおいて「欠陥が存在しないこと」の証明が不可能であるという考えを提唱しました。この理論は、悪魔の証明に似ています。つまり、どんなに要件やテスト条件を十分満たしたと考えられるテストケースを消化しても、「欠陥がない」ことは証明できないのです。

[対処例]
この問題に対処するために、逆説的な視点で捉えることが重要です。まず、テスト計画を立てる際には、テストの目的を明確にしましょう。それから、テストスコープを定義し、テスト対象の範囲を明らかにすることが求められます。これにより、テストのカバレッジを高めることができ、欠陥の発見確率を向上させることができます。しかし、どれだけカバレッジを高めても、絶対的な「欠陥が存在しないこと」の証明は不可能です。だからこそ、テストの目的やスコープ、カバレッジを適切に設定し、継続的にテストを実施することが、ソフトウェア品質を向上させるための最善の方法となります。

最終的には、欠陥が見つからないことを「正しさの証明」と捉えるのではなく、見つかった欠陥を修正し、未検出の欠陥のリスクを最小限に抑えることが重要になります。テストによって欠陥を抽出することは出来るが、先述したようにシステムの全ての層での動作の正常性を網羅的に担保することは難しく、さらに、テスト自体も人間が実施している以上、未知の欠陥が存在している可能性は0とは言えません。このため、テストでは、欠陥が存在しないことを証明することは出来ません。

原則 2: 全数テストは不可能 ~ISTQB:Exhaustive testing is impossible~

すべてをテストすること(入力と事前条件の全組み合わせ)は、ごく単純なソフトウェア以外では非現実的である。全数テストの代わりに、リスク分析、テスト技法、および優先度によりテストにかける労力を集中すべきである。

JSTQBより引用

[概要説明]
ITシステムの規模が拡大し続け、アプリケーションは複雑化の一途をたどるこのような状況で、ステークホルダーは「テストで問題がないことを証明したい」と考えることが多いです。しかし、全てのパターンを網羅する全数テストは、膨大な時間と組み合わせが必要であり非現実的です。原則1にあるとおり「欠陥が存在しないこと」の証明はできません。

この現実は、テスト専門家とステークホルダーとのギャップを表しており、システムの不具合を引き起こす遠因にもなります。
※マイヤーズの著書「ソフトウェア・テストの技法 第2版」でも「プログラムのすべてのエラーを見つけることは、非現実的でもあり、しばしば不可能でもある(※注 原典の要約)」と提唱しています。

[対処例]
全数テストの代案として、リスクベースドテストを採用することが効果的なケースもあります。リスクベースドテストでは、まずリスクを識別し、識別したリスクに対して影響度や発生率を考慮し、テストの優先度を決めていきます。プロジェクトにおいて、スケジュールや工数は有限であるため、リスクを適切に開示し、ステークホルダーと合意形成を図り、テストを進めていく事が重要です。リスク分析、テスト技法、および優先度によりテストにかける労力を集中することが、ソフトウェア品質を確保する上で現実的で効果的なアプローチとなります。

[一例の紹介]
ごくシンプルな構造のソフトウェアを除き、全ての入力値をチェックすることは不可能に近く、このため、テスト技法などを駆使して潜在的にリスクが潜んでいる可能性のあるパラメーターを選別してテストを行わなければなりません。

入力フォームの機能テストの場合

原則 3: 早期テストで時間とコストを節約 ~ISTQB:Early testing saves time and money~

早い段階で欠陥を見つけるために、静的テスト活動と動的テスト活動の両方をソフトウェア開発ライフサイクルのなるべく早い時期に開始すべきである。早期テストは、シフトレフトとも呼ばれる。ソフトウェア開発ライフサイクルの早い時期にテストを行うことにより、コストを低減または削減できる

JSTQBより引用

[概要説明]
ソフトウェア開発プロセスにおいて、後期になって欠陥が検出されると、修正作業や影響範囲の調査、原因分析に多くのリソースが必要となります。特に、結合テストやシステムテストの段階での欠陥発見は、スケジュールや人員配置の変更が必要となることが多く、大幅な遅延やコスト増加を招くことがあります。そのため、欠陥を開発初期に発見することが重要です。

[対処例]
開発初期に欠陥を発見するための手法として、「シフトレフト」というアプローチが推奨されています。このアプローチは、静的テストと動的テストをソフトウェア開発ライフサイクルのできるだけ早い段階で実施することを目指しています。静的テストには、インスペクションなどのレビュー形式を用いた、仕様書のレビュー、コードの静的解析などが含まれ、早期に仕様の問題を特定し、対処することができます。

シフトレフトの導入により、開発過程の早い段階で欠陥を発見し、工数やコストを削減することが可能になります。これにより、開発プロセスが円滑に進み、効率的に高品質なソフトウェアを開発することができます。

原則 4: 欠陥の偏在 ~ISTQB:Defects cluster together~

リリース前のテストで見つかる欠陥や運用時の故障の大部分は、特定の少数モジュールに集中する。
テストの労力を集中させるために欠陥の偏在を予測し、テストや運用での実際の観察結果に基づいてリスク分析を行う。

JSTQBより引用

[概要説明]
ソフトウェア開発プロジェクトでは、欠陥がソフトウェア全体に均等に分散しているとは限らず、
特定の機能やモジュール、クラスに集中することがよくあります。複雑さや難易度が高い機能、タイトなスケジュールで開発された部分、適切なレビューが実施されていない箇所など、特定の領域で欠陥が偏在する可能性が高まります。

[対処例]
この欠陥の集中傾向を見極め、テスト労力を最適に配分するためには、リスク分析が重要となります。
実際のテストや運用の観察結果に基づいてモジュール単位でリスク分析を行い、対策を立てることができます。

具体的な対策としては、メトリクスの測定やモニタリング、コントロールを実施し、特に複雑なモジュールに焦点を当てることが効果的です。たとえば、ソースコードのサイクロマチック複雑度を測定することで、欠陥が集中する可能性が高い部分を特定し、効率的なテスト計画を策定することができます。
このようなアプローチを取ることで、リソースの最適な配分を実現し、品質向上につなげることができます。

参考:「ミューテーションテスト」とは?アジャイル開発の時代に重要性が増している単体テスト。単体テストの確からしさを検証する「ミューテーションテスト」を紹介

原則 5: 殺虫剤のパラドックスにご用心 ~ISTQB:Beware of the pesticide paradox~

同じテストを何度も繰り返すと、最終的にはそのテストでは新しい欠陥を見つけられなくなる。この「殺虫剤のパラドックス」を回避するため、テストとテストデータを定期的に見直して、改定したり新規にテストを作成したりする必要がある(殺虫剤を繰り返し使用すると効果が低減するのと同様に、テストにおいても欠陥を見つける能力は低減する)。ただし、自動化されたリグレッションテストの場合は、同じテストを繰り返すことでリグレッションが低減しているという有益な結果を示すことができる。

JSTQBより引用

[概要説明]
ソフトウェアテストにおいて、同じテストを繰り返すことで新たな欠陥が見つからなくなる現象が「殺虫剤のパラドックス」と呼ばれます。これは、テスト担当者の経験に依存したり、状況に応じたテストの観点やバリエーションが不足しているために起こりえます。ソフトウェアテストに関して、新しい視点を常に取り入れる姿勢が重要である示唆でもあります。

[対処例]
このパラドックスを克服するためには、定期的にテスト仕様を見直し、新たな観点を取り入れることが重要です。また、レビューやチェック体制を強化し、異なる視点からのテストを行うことが効果的です。さらに、ユーザー視点を導入したり、探索的テストを実施することで、新たな欠陥を発見する可能性が高まります。

※ただし、リグレッションテストの場合は、同じテストケースを繰り返し実行することで、
コードの変更や追加に伴う不具合を検出し、品質を維持することが目的となっています。

参考:リグレッションテストとは?目的、実施タイミング、実施方法、自動化について解説

[イメージ図]
同じ成分で構成された殺虫剤を繰り返し使用していくと、それに耐性を持った虫が出現することで、いずれ効果がなくなってしまうのと同じように、同種のテストを何度も繰り返してばかりでは、最終的にそのテストでは新しい欠陥を見つけられなくなります。例えば、APIテストにおいて、入出力の観点でテストケースを作り、これを繰り返し実行していくと、そのテスト自体では次第に欠陥は発見されなくなります。そのため、別のパラメータを使ったテストケースの追加や、セキュリティやパフォーマンスなど、別の観点でのテストの実施を検討する必要があります。

原則 6:テストは条件次第 ~ISTQB:Testing is context dependent~

状況が異なれば、テストの方法も変わる。例えば、安全性が重要な産業用制御ソフトウェアのテストは、eコマースモバイルアプリケーションのテストとは異なる。また、アジャイルプロジェクトとシーケンシャルソフトウェア開発ライフサイクルプロジェクトでは、テストの実行方法が異なる

JSTQBより引用

[概要説明]
テスト手法は、対象となるシステムや環境、開発プロセスに応じて変化します。例えば、安全性が重要な産業用制御ソフトウェアのテストでは、ISO/IEC 20510の利用時品質モデルが重要視されるべきです。一方で、eコマースモバイルアプリケーションの場合は、決済処理に関わるトランザクション処理が主要な焦点となります。このように、システムの利用環境や性質によって適切なテスト方法を選択することが重要です。

[対処例]
対策として、ソフトウェアの特性に基づいてテスト計画を策定し、開発プロセスに適したテストプロセスを構築することが求められます。アジャイル開発の場合、開発と同時にテストを実施することで、効率的な品質確保が実現できます。各状況に適したテスト戦略を選択し、品質の高いソフトウェアを実現しましょう。

[イメージ図]
テストの対象物の性質や目的に応じて、テストの観点や内容を決定する必要があります。例えば、静的コンテンツしかほぼ存在しないホームページと、社内の全てのリソースの集中管理をするERPとではテストの際に必要となる観点や実施レベルは大きく異なります。

原則 7:「バグゼロ」の落とし穴 ~ISTQB:Absence-of-errors is a fallacy~

テスト担当者は可能なテストすべてを実行でき、可能性のある欠陥すべてを検出できると期待する組織があるが、原則2と原則1により、これは不可能である。また、大量の欠陥を検出して修正するだけでシステムを正しく構築できると期待することも誤った思い込みである。例えば、指定された要件すべてを徹底的にテストし、検出した欠陥すべてを修正しても、使いにくいシステム、ユーザーのニーズや期待を満たさないシステム、またはその他の競合システムに比べて劣るシステムが構築されることがある。

JSTQBより引用

[概要説明]
「バグゼロ」を目指すことは一見理想的に思われるものの、すべての欠陥を発見して修正しただけでは
高品質なシステムが保証されるわけではありません。ユーザーニーズや性能、信頼性などの品質指標を満たさないシステムが完成することも考えられます。さらに、過剰なチェックポイントを設けることで、リソースが圧迫され、重要な優先順位を見落とすこともあります。

[対処例]
対策として、品質実現に向けたプロセスと人材を重視し、各フェイズでのコミュニケーションを強化することが重要です。品質の定義を明確にし、ステークホルダーとの合意を確立し、様々なアプローチを用いて開発を進めましょう。欠陥が完全にゼロにはならないことを前提に、ビジネスロジック、運用や保守、技術、人の観点から品質保証を実現することが求められます。

当たり前のことですが、いくら欠陥を見つけてソフトウェアの不具合を修正したところで、構築したシステムが使えなかったり、ユーザー要件や期待を充足させられなければ意味がありません。例えば、不具合報告がほとんどないスマートフォンゲームが存在したところで、ストアからダウンロードされず、プレイされていなければ意味がありません。それは、テストという行為は生産活動そのものではないためです。

これらの原則を意識することで、テストの効率化が図れると考えられておりますので、皆様も是非こうした考え方を頭の片隅に入れておいていただければと思います。

まとめ

・人為的なミスがプロダクトの欠陥として顕在化し故障の原因につながる
・テストの目的は「ソフトウェアが仕様書通りの挙動となっているかチェックし、システムに欠陥がないことを確認する」ことにある
・効率的なテストの実施のヒントは「ソフトウェアテストの7原則」にある

<おすすめ記事・メディア>

Web・GUIアプリのテスト自動化ツールなら「Testablish」

SHARE

  • facebook
  • twitter

SQRIPTER

Sqripts編集部

記事一覧

Sqripts編集部がお役立ち情報を発信しています。

Sqriptsはシステム開発における品質(Quality)を中心に、エンジニアが”理解しやすい”Scriptに変換して情報発信するメディアです

  • 新規登録/ログイン
  • 株式会社AGEST