ソフトウェアテストとは?20種類以上のテストを分類ごとに徹底紹介
開発工程が完了したソフトウェアについては、製品として仕様を満たしているか、不具合がないかなど、さまざまな観点からテストが行われます。ソフトウェア開発は継続的な改変が前提とされており、テストプロセスも複雑です。そのため、ソフトウェアテストも、複数の手段を組み合わせて行うのが一般的です。本記事では、ソフトウェアテスト目的や種類、また抱える課題について紹介します。
ソフトウェアテストとは
ソフトウェアテストは、開発を終えたソフトウェアが製品としての仕様を満たしているか、チェックする工程です。以下では、ソフトウェアテストの目的と「ソフトウェアテストの7つの原則」について紹介します。
①ソフトウェアテストの目的
ソフトウェアテストの目的は、ソフトウェアの品質保証です。
ソフトウェアは非常に複雑な構造をしており、規模が大きくなるにつれて、開発者が予期しない不具合が発生する確率も高まります。ソフトウェアに不具合を残したまま製品がリリースされ、利用者の手で不具合が見つかった場合、大きな問題に発展する可能性もあります。
このようなリスクを抑えるために、開発が完了したソフトウェアに関する多角的な観点からの検証が行われます。
②ソフトウェアテストの7原則
ソフトウェアテストに関する国際的な資格認証を行うISTQB(International Software Testing Qualifications Board:国際ソフトウェアテスト資格認定委員会)では、あらゆるテストで共通に使える一般的なガイドラインとして「ソフトウェアテストの7原則」を定めています。以下では、その内容を引用します。
テスト技術者資格制度 Foundation Level シラバス│ISTQB
https://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018V31.J03.pdf
(1)不具合があることしか示せない
テストにより、欠陥があることは示せるが、欠陥がないことは証明できない。テストにより、ソフトウェアに残る未検出欠陥の数を減らせるが、欠陥が見つからないとしても、正しさの証明とはならない。
(2)全数テストは不可能
すべてをテストすること(入力と事前条件の全組み合わせ)は、ごく単純なソフトウェア以外では非現実的である。全数テストの代わりに、リスク分析、テスト技法、および優先度によりテストにかける労力を集中すべきである。
(3)早期テストで時間とコストを節約
早い段階で欠陥を見つけるために、静的テスト活動と動的テスト活動の両方をソフトウェア開発ライフサイクルのなるべく早い時期に開始すべきである。早期テストは、シフトレフトとも呼ばれる。ソフトウェア開発ライフサイクルの早い時期にテストを行うことにより、コストを低減または削減できる。
(4)欠陥の偏在
リリース前のテストで見つかる欠陥や運用時の故障の大部分は、特定の少数モジュールに集中する。テストの労力を集中させるために欠陥の偏在を予測し、テストや運用での実際の観察結果に基づいてリスク分析を行う。(原則2で触れたことと同様)。
(5)殺虫剤のパラドックス
同じテストを何度も繰り返すと、最終的にはそのテストでは新しい欠陥を見つけられなくなる。この「殺虫剤のパラドックス」を回避するため、テストとテストデータを定期的に見直して、改定したり新規にテストを作成したりする必要がある(殺虫剤を繰り返し使用すると効果が低減するのと同様に、テストにおいても欠陥を見つける能力は低減する)。ただし、自動化されたリグレッションテストの場合は、同じテストを繰り返すことでリグレッションが低減しているという有益な結果を示すことができる。
(6)テストは条件次第
状況が異なれば、テストの方法も変わる。例えば、安全性が重要な産業用制御ソフトウェアのテストは、eコマースモバイルアプリケーションのテストとは異なる。また、アジャイルプロジェクトとシーケンシャルソフトウェア開発ライフサイクルプロジェクトでは、テストの実行方法が異なる。
(7)「バグゼロ」の落とし穴
テスト担当者は可能なテストすべてを実行でき、可能性のある欠陥すべてを検出できると期待する組織があるが、原則2と原則1により、これは不可能である。また、大量の欠陥を検出して修正するだけでシステムを正しく構築できると期待することも誤った思い込みである。例えば、指定された要件すべてを徹底的にテストし、検出した欠陥すべてを修正しても、使いにくいシステム、ユーザーのニーズや期待を満たさないシステム、またはその他の競合システムに比べて劣るシステムが構築されることがある。
これらの記述からわかるように、ソフトウェアテストは画一的に設計、実施できるものでもなければ、品質保証において必ずしも万能な役割を果たすこともありません。
ソフトウェアテストの実施者は、ソフトウェア開発の目的やユーザーへの理解を深めた上で、コンテキストに即した最適なテストの設計と実施が求められます。
ソフトウェアテストの種類
ソフトウェアテストは、ソフトウェアの規模や特徴に応じて、多種多様な手法が活用されています。以下では、主なソフトウェアテストの手法について分類し、それぞれの特徴について紹介します。
①動的テストと静的テスト
動的テストはプログラムコードを実行して行うテストです。
実装が完了したソフトウェアを手元で動かしてみて、製品仕様を満たしているか、意図しない挙動やバグが発生していないか、チェックを行います。テスターはプログラムの内部状態を把握せずにテストを実施します。
一方、静的テストではプログラムコードを実行しません。
ソフトウェアのソースコードを対象に、第三者によるコードレビューや、コード解析ツールによる分析を行います。ソフトウェアの内部構造を細かくチェックするため、実装ミスや仕様漏れを開発プロセスの早期に解決できます。
動的テストと静的テストは、どちらか一方を実施すればいいというものではありません。相互補完的に実施することで、ソフトウェアの品質向上を実現します。
②開発工程毎のテスト
システム開発の開始から終了までの一連の流れについて、開発工程とテスト工程の対応関係を示した図がV字モデルです。
V字モデルにおける開発工程は、要求分析・要件定義・基本設計・詳細設計の4段階です。その4つの開発工程に対して、受入テスト・システムテスト・結合テスト・単体テストが順に対応関係にあります。
開発 | テスト |
要求分析 | 受入テスト |
↓ | ↑ |
要件定義 | システムテスト |
↓ | ↑ |
基本設計 | 統合テスト |
↓ | ↑ |
詳細設計 | 単体テスト |
以下では、4つのテスト工程について紹介します。
(1)単体テスト(Unit Test)
ソフトウェアテストが可能な最小単位をユニットと呼びます。ユニットは厳密に定義されているわけではなく、ソースコード上で個々の関数やクラスをユニットとすることもあれば、画面や機能単位でテストを行うこともあります。
単体テストはテスト範囲が狭いこともあり、開発者がテスト設計を行い、自動で行われるのが一般的です。
(2)結合テスト(Integration Test)
単体テスト完了後に、2つ以上のコンポーネントやモジュールを組み合わせて、ソフトウェアが満たすべき機能要件に沿って動作検証を行うのが結合テストです。
個々のモジュール間におけるデータの引き渡しや、機能の一連のフローにおける異常、イレギュラーな操作によるシステム不具合の有無、などをチェックします。
単体テストに比べてテスト範囲や条件の組み合わせが膨大になるため、テスト実行の負荷が大きく、細かな異常や問題に気づきにくくなる点に注意が必要です。
(3)システムテスト(System Test)
結合テストが完了したすべてのコンポーネント・モジュールを用いて、システムの一連の流れをエンドユーザーの利用を想定して検証するのがシステムテストです。
プログラムが動作するネットワークやサーバーといった環境についても、本番環境と同様の条件を揃えます。システムのユーザービリティやセキュリティ、システムに負荷をかけた場合の性能など、実運用を想定した観点についてテストを行います。
(4)受入テスト(Acceptance Test)
受入テストは、V字モデルにおける最後のテスト工程です。完成したソフトウェアが要求した機能や性能を備えているか、ソフトウェア開発の依頼者がテストします。
たとえば、外部ベンダーへ依頼しソフトウェア開発を行なっている場合、依頼した企業側は、システム運用に支障がないか、契約書や規定への準拠、ビジネスロジックとの一致などの観点でテストが行われます。
テスト内容はシステムテストと多くの点で重なりますが、テストの主目的が不具合の発見ではなく、製品の検収である点がポイントです。
③機能テスト
機能テストはユーザーが求める機能について、システムが必要な仕様を満たしているかどうかを検証するテストです。基本的に、機能テストのテスターはソフトウェアの内部構造を知りません。
以下では代表的な4つの機能テスト手法を紹介します。
(1)スモークテスト
スモークテストは、テスト環境上にデプロイされたソフトウェアの動作を、開発者が確認する手法です。本格的なソフトウェアテストを開始する前工程として実施されます。
ソフトウェアの開発プロセスでは、修正や機能追加が頻繁に起こります。変更に伴い、ソースコードは都度ビルド・コンパイルされて、テスト環境にデプロイされます。しかし、ビルドやコンパイルが失敗して、ソフトウェアが動作しないまま次の工程に進んでも、テスターはテストを開始できません。
このようなコミュニケーションロスを頻発させないために、動作保証可能な最低限のテストを開発者が行うのです。
(2)サニティ(健全性)テスト
サニティテストは、一般的に、バグ修正などの限られた範囲でのソフトウェアの変更について、期待通りに動作するかを素早くチェックするテストです。スモークテストの後工程で、リグレッションテストのサブセットとして実施されます。
スモークテストは、ソフトウェアの動作に必要な最低限の基本的機能など、浅く広くテストを行う一方、サニティテストはソースコードの「変更箇所のみ」に限った、深く狭いテストといわれています。
(3)リグレッション(回帰)テスト
ソフトウェアに変更が加えられた際、あらためて変更前と同じテストを再実行するのがリグレッションテストです。
ソフトウェアの変更には、新たなバグ発生の可能性が常に伴います。ある一箇所に対する修正が、他の箇所の不具合を引き起こすのです。変更を加えるたびにテスト範囲が拡大することから、テストスイート(複数のテストケースの集合体)を自動実行する環境が活用されています。
(4)ユーザビリティテスト
ユーザビリティテストは、ソフトウェアの使いやすさ(操作性や視認性等)を検証するテストです。
たとえば、文字の大きさや、ボタンの記載内容など、ユーザーを誤解させる表現や配置がないかは検証項目の一例です。
テスターはソフトウェアの操作方法について、利用開始から目的達成まで一連のステップを設計します。そして、ステップ毎にUIやUXがユーザーの思考・利用状況・目的に沿ったものになっているか、利用者のつまずくポイントがないかどうかを確認します。
また、利用者の障壁となる課題を洗い出すだけでなく、利用者の感情についてもヒアリングを行い、ストレスなく機能が利用できるまで、複数回の機能改善とテスト実施が推奨されます。
④性能(パフォーマンス)テスト
性能テストは、ソフトウェアに対する信頼性や安定性を検証するテストです。以下では、4つ性能テスト手法について紹介します。
(1)ロードテスト(負荷テスト)
ロードテストでは、意図的に複数のユーザーからのアクセス等を発生させることで、ソフトウェアの処理性能をテストします。
テストは同時接続数やデータ件数、データサイズについて負荷の程度をいくつかのパターンに整理した上で、各パターンの状況下でシステムが正しく動作することを確認します。
(2)ストレステスト(限界テスト)
想定以上の負荷を発生させた場合、ソフトウェアがどのように動作するかを確認するのがストレステストです。処理速度が低下しても最低限ソフトウェアが動作するかどうか、データの不整合が生じないか、などについて検証を行います。
(3)ロングランテスト(耐久テスト)
ロングランテストでは、ソフトウェアを長時間運用することで発生する不具合等がないかを確かめます。
ソフトウェアによっては、時間を経るごとに処理の待機待ちが増えて、メモリ不足や性能劣化が発生します。たとえば、大規模なECサイトにおいて、購入後のフォローで数週間後におすすめの商品についてメール配信を行うケースがあるとします。ユーザー数が増加すると、待機待ちのメールも増えるため処理に支障が出る可能性があります。このような場合を想定し、ロングランテストは実施されます。
(4)スパイクテスト
ロードテストやストレステストでは負荷を段階的に引き上げるのに対して、スパイクテストでは瞬間的にソフトウェアの性能限界以上の負荷をかけます。このような状況下において、データの不整合やシステム停止が発生しないかを確認します。
⑤結合テスト
結合テストはテストの進め方によっていくつかの種類に分類できます。以下では、結合テストの代表的な3つのアプローチについて紹介します。
(1)トップダウンテスト
トップダウンテストは、システムの上位のモジュールから順にテストを行います。
システムの中枢的な機能の問題を早期に発見できる点がメリットです。一方、テスト実行段階では下位のモジュールの開発が完了していないため、スタブと呼ばれるダミーモジュールが大量に必要です。
(2)ボトムアップテスト
ボトムアップテストは、下位の開発完了したモジュールから順にテストを行います。
末端のモジュールからテストを行うため、実装とテストの並行作業がスムーズです。一方で、上位のモジュールのテストが後回しになるため、システム中枢の機能や一連のフローに潜む問題の発見に課題が残ります。
(3)ビッグバンテスト
ビッグバンテストはすべてのモジュールの実装が完了した上で、一連の機能について一気通貫でテストを行う手法です。
トップダウンテストやボトムアップテストに比べてテストにかかる工数を抑えられます。一方で、ソフトウェアの規模が大きくなるとテストケースが複雑化して、網羅的なテストの実施が難しくなります。
⑥ブラックボックステスト
ブラックボックステストは、テスターがソフトウェアの内部構造を把握することなく、システムの入力と出力の整合性をチェックするテストです。以下では、ブラックボックステストの代表的な4つの手法を紹介します。
(1)同値分割法
同値分割法は入力値の候補のグループ分けを行い、各グループで代表的な1つの入力値を選択してテストを行います。同じグループに分類された入力値はすべて同じ処理が行われます。
たとえば、入力された数字の「桁数」を数えるプログラムを考えた場合、正しく動作していれば「0〜9」の入力に対しては「1」、「10〜99」の入力に対しては「2」が出力されます。それぞれのグループで代表的な1つの入力値を入れて、プログラムが正常に動作していれば、他の数値でも同様の処理が行われるだろうと推測できます。
グループ分けが行われることでテストケースを大幅に削減できる点がメリットです。
(2)境界値分析
境界値分析は同値分割法で用いたグループの境界値を入力値としてテストします。境界付近のバグを効率的に発見できる点がメリットです。
たとえば、10以上20未満、20以上30未満とグループを定義した場合、開発者が「以下」と「未満」を見間違えて、20や30といった値が、意図しないグループに含まれる可能性が考えられます。
同値分割法と併用することで、効果的なテストを実現します。
(3)デシジョンテーブル(決定表)
デシジョンテーブルは、入力と出力の組み合わせを網羅的に洗い出して表にまとめる手法です。
複数の入力条件が組み合わさるような、複雑な機能に対して有効です。網羅性も可視化されるため、チーム内での認識齟齬も抑えられます。一方、組み合わせが増えると、テストケースの作成やテスト実施の工数の時間も増加する点に注意が必要です。
(4)シナリオテスト
シナリオテストは、ソフトウェアの一連の利用手順について期待される動作を洗い出し、実際の操作を行って問題が生じないかテストを行います。
テストにあたっては、ユースケース図や業務フローに関するドキュメントが必要です。
ECサイトのように販売者と購入者がいて、一連の操作が一人のユーザーで完結しない場合、それぞれのユーザー向けの画面を交互に確認します。また一連の利用手順について操作が前後した場合、データの不整合が発生しないかどうかについても検証を行います。
⑦ホワイトボックス(構造)テスト
ホワイトボックステストは、構造テストとも呼ばれ、ソフトウェアの内部構造を対象にテスを行うテストです。テスターにはプログラミングの知識が求められます。以下では、代表的な2つのホワイトボックステスト手法を紹介します。
(1)制御フローテスト
制御フローテストは、プログラムの分岐条件について、すべての分岐を一度は実行するようにテストを行います。
複雑なモジュールの場合、条件分岐のパターンが指数関数的に増大するため、組み合わせの一部を対象にしたテスト設計が一般的です。
(2)データフローテスト
データフローテストは、プログラム内部で利用されるデータの流れに着目したテストです。
データはプログラム内で変数として定義され、定義→使用→消滅というライフサイクルで使用されます。この流れをデータフローと呼びます。制御フロー内において利用されるデータが、定義される前に使用されている場合、データフローと整合性が取れません。
このようなデータフローの不整合の検証が、データフローテストをする目的です。
⑧その他のテスト技法
以下では、上記項目では明確な分類が難しい、その他のソフトウェアテスト技法について紹介します。
(1)探索的テスト
探索的テストでは、テストケースを事前に設計しません。
テスターは過去の経験や学習をベースにテストを実行し、その過程や実行結果からテストの最終的な目的や範囲を決定します。テストの実施に必要な設計書や、仕様書の準備がなくなるため、スピード感のあるテストが可能です。
一方で、非常に属人性が高く、テストケースの網羅性も担保されないため、要件や仕様が明確に決まっているようなソフトウェアのテストには不向きです。
一般的には、ソフトウェアテストを探索的テストのみで実施するケースは少なく、ドキュメンテーションをベースとする記述式テストと補完関係を持ちながら、テストが行われます。
(2)モンキーテスト
モンキーテストは、テスターがテストの対象や操作手順を定めずに、その場の思いつきでソフトウェアを操作して不具合等がないかを検証する手法です。アドホックテストやゲリラテストとも呼ばれます。
通常のテストでは見つけられない、予期せぬ不具合を検出できる点がメリットです。一方、デメリットとして、不具合が発見されても手順が記録されておらず、再現ができない場合があります。またテストが構造的に設計されておらず品質の評価につながりにくい点や、必ずしも不具合が見つかるわけではない点にも注意しましょう。
(3)ストーリーテスト
ストーリーテストはアジャイル開発におけるソフトウェアテスト手法です。
アジャイル開発では開発期間を数週間で区切り、機能単位で要件定義・デザイン・開発・テストのプロセスを1周します。アジャイル開発ではこの機能単位をユーザーストーリーと定義します。
ストーリーテストは、ユーザーストーリーに含まれる機能を対象にテストが実施されます。ストーリーテストでは、利用者の行動過程と心理状態を想定したテスト設計が必要で、利用者に対する深い理解が求められます。
ソフトウェアテストにおける課題
日本でも大手金融機関のシステム障害やアプリの不具合などが、メディアで取り上げられる機会が増えています。
すべての問題がソフトウェアテストに起因するわけではありませんが、ソフトウェアテストで防げた不具合も少なくないはずです。一方、ソフトウェアテストを実施するにも、人材やテスト環境に課題が残ります。
①専門性ある人材や組織体制
ソフトウェアテストの作業は非常に膨大で、専門性を求められる領域です。
テストツールの選定、ユーザーのニーズに沿ったテスト設計など、ソフトウェアとユーザーの両方に対して深い理解が必要です。このようなスキルやノウハウを持った人材は世の中でも希少で、専門性のある人材を採用できるとも限りません。
また、ソフトウェアテストは対象デバイスや入力条件を増やすことで、テストパターンとテスト実施工数をいくらでも増やすことができます。そのため、「誰が、どの程度、テストプロセスに作業時間を充てるのか」の見極めも肝要です。
開発者・テスターが互いに協力しながら、最適なソフトウェアテストの実行体制を検討・構築する必要があります。
②ソフトウェアの拡張開発と対象デバイス
ソフトウェアは、開発規模が拡大するにつれて複雑性が増します。
その要因は、提供する機能の増加拡張だけでなく、スマホやタブレットなど、サービスが対応するデバイスやプラットフォームにも依存します。とくにスマホは世界中に数えきれないほど多くのメーカー・機種・OS・バージョンが存在しており、網羅的なテストは現実的ではありません。
ソフトウェアテストの実施にあたっては、ユーザーの属性等に応じてテスト対象デバイスに優先度付けを行い、現実的な範囲で品質保証しなければならないのです。
まとめ
ソフトウェアテストは、ユーザーが必要とする機能の検証に限らず、顧客体験の向上や、世界中で増加するサイバー攻撃への備えとしても重要な意味を持ちます。
しかし現実には、人的リソースやソフトウェアテスト自体の難しさなど、多くの課題があります。
そのため、必要十分なソフトウェアテストを行うためには、テスターの採用に限らず、テストツールの活用や専門機関への外部委託も選択肢として考えられます。
Applauseは、世界200以上の国・地域で70万名以上のテスターを抱える、世界最大級のクラウドテストソリューションです。
年齢、性別、居住地、言語、略歴等の細かいプロファイルの中から、プロダクトがターゲットとするユーザー属性とマッチしたテスターをアサインし、実践的なテストやフィードバックを実現します。
また、ソフトウェアテストは、手動テスト・自動テスト両方を組み合わせた統合テストにも対応しています。ソフトウェアテストでお困りの際は、お気軽にご相談ください。