ソフトウェアテスト

ソフトウェアテスト  は、コンピュータのプログラムから仕様にない振舞または欠陥を見つけ出す作業のことである。ソフトウェアテストで見つかったプログラム中の欠陥を修正する作業をデバッグという。ソフトウェアテストに成功するとは、テストで欠陥が発見されるか、規定した試験項目にすべて合格するか、規定した品質目標に到達することである。目標とした品質には、規定した試験項目にすべて合格することもある。例えば、OS, プログラミング言語では、仕様を満たしているかどうかの適合試験を規定している。ソフトウェアテストでは、欠陥が存在することを示すことはできるが、欠陥が存在しないことは証明できない。ソフトウェアに仕様にない振舞がないことを保証する作業を証明といい、証明用のシステム、証明しやすい言語も多数存在している。本項では動的なソフトウェアテストを中心に扱う。

1. 目的
-----

ソフトウェアテストの目的には以下が挙げられる。

作業成果物の評価による欠陥の防止
明確にした要件を満たすかの検証
完成の確認・動作の妥当性確認
テスト対象の品質に対する信頼を積み重ねて、所定のレベルにあることの確証
欠陥の作りこみ防止
故障・欠陥の発見、それによる不十分なソフトウェア品質リスクレベルの低減
意志決定のための情報提供
契約上、法律上、または規制上の要件や標準の遵守、また/あるいは準拠の検証

1.1. 変更への信頼
-----------

ソフトウェアテストは「変更への信頼」を生むことでソフトウェアの品質・提供速度を向上させる目的・効果を持つ。

ソフトウェアの変更は既存コードの破壊によるバグを引き起こしうるため、ソフトウェアエンジニアに対し、コード変更への心理的ハードルとして作用する。このハードルは変更への躊躇いを生み、品質向上の機会を減少させてしまう。

リグレッションテストはコード変更によるバグを発見して欠陥の作りこみを防止し、品質に対する信頼を積み増す。この効果により、新たな変更が既存コンポーネントを破壊しないという信頼・安心がエンジニアに生まれる。結果として良い変更の頻度があがり、ソフトウェアの品質・提供速度が向上する。

ただし、一度書かれたソフトウェアが「決して変更されない」場合にはこの効果が発揮されない。

2. 動的テストと静的テスト
--------------

プログラムを実際に動かしてみて行うテストを動的テストと呼び、プログラムを実際に動かしてみることなくソースコードやオブジェクトコードを検証する作業を静的テストと呼ぶ。静的テストには、ツールを用いた静的コード解析の他に、人手で行うコードレビュー、ウォークスルー、インスペクションなどがある。多くの場合、意識されることはないが、コンパイラまたはプリコンパイラはソースコードを静的にテストする。

3. 性能試験と機能試験
------------

機能試験・性能試験の指標と分類にISO/IEC 9126  の枠組みを利用することがある。

3.1. 機能試験 
-------------------------

機能試験は、規定した機能を果たすかどうかを試す。 関数であれば、規定した引数を与えると、想定した戻り値を返すブラックボックス試験が機能試験に相当し、単体試験の一部である。 適合試験、単体試験は、機能試験を主とするが、性能試験を含むことがある。

3.2. 性能試験 
----------------------------

性能試験は、ソフトウェアシステムの性能を測り、必要な性能が出ることを確かめる試験である。入力をどれだけ受付けるか、どれだけの出力が可能か。通信経路数・通信速度、処理件数などプログラム単体では問題が発生しなくても、通信、データベース、入出力 、同時に起動するソフトウェアなどの高負荷、長時間使用などの条件下では性能が低下することがある。性能を確認する試験は、システムの性能に影響を与えないように測定する必要があるため、OSやミドルウェアなどでは性能を測定する効率的な計測方法を提供していることもある。 性能試験は、単体試験から実施する場合と統合試験から実施する場合とがある。 過負荷に対する性能試験をストレステストという。

3.2.1. ストレステスト
--------------

ストレステストは、ソフトウェアシステムに対して高い負荷を与え、処理の低下・抜け、データの破壊、発熱など致命的な問題が、どういう条件で発生するかを試験する。ストレステストを行うことで、高い負荷が加わっている状況でしか発生しない不具合や、発生確率の低い欠陥、著しい性能の低下を発見することがある。性能試験の一部として実施し、対応可能な付加の仕様を確かめることがある。

4. 検証試験と妥当性確認試験
---------------

仕様通りに動いているか、試験仕様に基づいて確認する試験を検証試験 、エンドユーザーの意図通りに動いているかどうかを確認する試験を妥当性確認試験  という。

4.1. 検証試験 
-----------------------------

決めた仕様に合致しているかどうかを試す試験。プログラミング言語、OS、通信規約、データベースなどの仕様に合致しているかどうかを試す試験を適合試験ということがある。

4.1.1. 適合試験 
------------------------------

OS、プログラミング言語、ネットワーク通信プロトコル、データベースなどソフトウェアを動かすための基本的なプラットフォームが、仕様に適合しているかどうかを確認する検証試験 。OSの国際規格の一つであるPOSIXでは、 NIST が適合試験のソースコードを公開している。 自動車用OSの国際規格OSEKでは、MODISTARC  がある。 TOPPERS OSでは、TTSP  というテスト環境を提供し、適合テスト等を実施しやすくしている。 プラットフォームの適合試験を実施せずに、アプリケーションソフトウェアの試験を実施すると、プラットフォーム仕様の変化に対応できていないことがある。

4.2. 妥当性確認試験 
------------------------------

エンドユーザーが意図している動作をするかどうかを試験することを妥当性確認試験という。 性能試験、システム試験、受入試験の一部として実施することがある。

5. 上から  と下から 
----------------------------------

全体が完成してからテストをすることをビッグバンテストという。規模の小さなプログラムであれば、この手法でうまくいく場合もある。この手法は大規模なプログラムに対して適当でない。なぜなら、大規模なプログラムを一気にテストをして問題が発生したときに、問題の原因を巨大なプログラム中から探すのが困難だからである。また、ソフトウェア中に複数のバグが存在する場合、それらのバグが相互に影響しあい、バグの原因の特定がさらに困難になる場合もある。そのため、ソフトウェアテストでは、最初に単体テストによってモジュール単位のテストを行う。単体テストの問題で、十分にモジュール単位のテストが終わったら、結合テストまたはシステムテストに進む。また、小規模なプログラムであっても、単体テストを行わずに結合テスト又はシステムテストへ入るのはテスト全体の効率を下げる。しかし、再利用性が高く、時間についての制約だけが中心の試験の場合は現場でビッグバンテストを行う場合がある。

5.1. 下降試験 
-------------------------

単体テストおよび結合テストにおける手法の一つ。単体テストが完了したモジュールのうち、上位モジュールから順に結合させてテストを行なう。この手法の利点は、仕様的な振る舞いを決定する上位モジュールを早期に検証することによって、機能漏れ、仕様の認識違いなどの致命的な不具合を、開発の早い段階で発見できることにある。一方で、数の多い下位モジュールの検証が先送りされるため、開発と平行してテストを進めにくいという欠点もある。

トップダウンテストを行う際には「テストスタブ」を用意しなければならない。

5.2. 上昇試験 
--------------------------

単体テストおよび結合テストにおける手法の一つ。トップダウンテストとは逆に、単体テストが完了した下位モジュールから順に結合させてテストを行なう。この手法の利点は、数が多く独立性の高い下位モジュールから順に検証することで、開発とテストを平行して実施できることにある。一方で、システムの根幹となる上位モジュールで不具合が発見された場合、テストが完了したはずの下位モジュールも影響を受けるという欠点も持っている。単体試験を行う場合に、他の関数等を呼び出している関数を試験する場合に、呼出のない関数を試験してから、呼出をしている試験を行う場合にボトムアップテストになっている。

ボトムアップテストを行う際には「テストドライバ」を用意しなければならない。

6. ホワイトボックステストとブラックボックステスト
--------------------------

プログラムの内部構造に注目したテストをホワイトボックステスト 、プログラムの入力と出力に注目したテストをブラックボックステスト  という。

6.1. ホワイトボックステスト 
---------------------------------

ホワイトボックステスト  は、プログラムの構造に着目したソフトウェアテストのことである。着目する構造には命令や分岐などがあり、注目した構造に対してどれだけの割合の部分を実行できたかを網羅率で表す。

int abs { if  { x = -x; } return x; }

6.1.1. 命令網羅  
-------------------------------------

命令網羅基準を用いてテストを行う場合は、すべての命令を実行すればよい。上記のabs関数では、x = -1 を用いてテストすれば命令網羅基準に従ってテストできたことになる。

6.1.2. 分岐網羅  
----------------------------------

判定条件網羅  とも。分岐網羅基準を用いてテストを行う場合は、すべての分岐において、すべての分岐の方向を実行すればよい。上記のabs関数では、x = -1とx = 0を用いてそれぞれテストすれば、分岐網羅基準にしたがってテストできたことになる。分岐網羅は命令網羅の基準を満たす。

6.1.3. 条件網羅  
-------------------------------------

条件網羅基準を用いてテストを行う場合は、各々の個別条件について、全ての可能な結果を少なくとも1回はとるように実行すればよい。条件網羅基準は分岐の方向を意識しないため、分岐網羅・命令網羅の基準を満たさないことがある。

なお、判定結果に影響を与えない真理値に関しては省略しても良い。例えば判定条件: x > 0 || y > 0 に対して条件網羅性を満たすようにテストする場合、単純にテストするとx > 0の真偽、y > 0の真偽の両方を考慮して4通りのテストが必要になるが、x > 0が真の場合にはy > 0の真偽は判定条件に影響しないことを考慮すれば、以下の3通りのテストをすればよいことがわかる。

x > 0 かつ y > 0
x <= 0 かつ y > 0
x <= 0 かつ y <= 0

6.1.4. 判定条件／条件網羅 
----------------------------------------------

判定条件／条件網羅基準を用いてテストを行う場合は、各々の個別条件について全ての結果を少なくとも1回はとるようにし、かつ各々の分岐について全ての分岐の方向を実行すればよい。

6.1.5. 複合条件網羅 
-------------------------------------------

複合条件網羅基準を用いてテストを行う場合は、それぞれの判定における全ての結果の全ての可能な組み合わせを少なくとも1回はとるように実行すればよい。ただし、ある組み合わせは作ることが不可能である場合がある。たとえば、条件  と  とでは、可能な組み合わせは3つしかない。

6.1.6. 経路網羅 
---------------------------

経路網羅基準を用いてテストを行う場合は、すべての経路が少なくとも1回はとるように実行すればよい。反復構造を持つプログラムの全ての経路を特定することは普通は不可能であるから、この場合、完全な経路網羅は実行可能な目標とは考えられない。

6.2. ブラックボックステスト 
---------------------------------

ブラックボックステスト  は、プログラムの入出力だけに注目し仕様通りにプログラムが動作するかをテストする。プログラムの入力が単一の値である場合は同値分割や限界値分析を、プログラムの入力が複数あり相互に影響を与えるような場合は決定表や原因結果グラフなどを用いて入力を決定する。大域変数の読み書き、通信、割り込みなどが処理中にある場合には、それらも入出力の一つとして扱う。

6.2.1. 同値分割
-----------

入力または出力を同じように扱えるグループに値を分けたものを同値クラスと呼び、それぞれの代表的な値を用いてテストを行う。 有効な同値クラスを有効同値クラス、無効となる同値クラスを無効同値クラスと呼ぶ。

6.2.2. 限界値分析
------------

入力または出力を同じように扱えるグループに値を分け、その境界となる値を用いてテストを行う。プログラムのエラーは分岐の境界で発生する場合が多いため、限界値分析に基づいたテストを行うことで、同値分割に基づいたテストよりも多くの欠陥を発見することができる。

6.2.3. 同値分割と限界値分析の適用例
---------------------

例えば、次のようなプログラムがあったとする。

入力: 時刻 
出力: 10:00≦入力≦20:00であれば通常料金、それ以外であれば割増料金通常料金の同値クラスは10:00以上20:00以下。 割増料金の同値クラスは0:00以上10:00未満と20:00を超え23:59以下。 無効同値クラスは0:00未満と23:59より大きい場合となる。 　 　　　　　0:00　 10:00 　　 20:00 23:59 －－－－○●－－－－－－－－○●－－－－－－－－－●○－－－－－－－－●○－－－ 無効同値　　　　同値クラス　　　　　同値クラス　　　　　同値クラス　　　　無効同値 クラス 　　　 　(割増料金）