ソフトウェアテスト

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

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

* 作業成果物の評価による欠陥の防止（例: 要件、ユーザーストーリー、設計、コード）

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

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

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

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

ただし、一度書かれたソフトウェアが「決して変更されない」場合にはこの効果が発揮されない。（参考: テスト駆動開発）

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

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

### 機能試験 (Function Test)

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

### 性能試験 (Performance Test)

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

#### ストレステスト

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

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

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

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

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

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

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

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

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

### ホワイトボックステスト (White Box Test)

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


```c
int abs(int x) {
  if (x < 0) {
    x = -x;
  }
  return x;
}
```


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

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

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

なお、判定結果に影響を与えない真理値に関しては省略しても良い。例えば判定条件:

```c
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`
# `x <= 0` かつ `y <= 0`

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

#### 複合条件網羅 (Multiple Condition Coverage)
複合条件網羅基準を用いてテストを行う場合は、それぞれの判定における全ての結果の全ての可能な組み合わせを少なくとも1回はとるように実行すればよい。ただし、ある組み合わせは作ることが不可能である場合がある。たとえば、条件 (A > 2) と (A 
int isCompositeNumber(int x) {
  return !isPrimeNumber(x);
}


上記のプログラムは、与えられた値が合成数かどうかを判定するプログラムである。このプログラムをテストするために必要な**テストドライバ**と**テストスタブ**の例を示す。

### テストドライバ

```c
int main() {
  int num;
  for (num = 2; num <= 10; num++) {
    if (isCompositeNumber(num)) {
      printf("%d is a composite number", num);
    } else {
      printf("%d is not a composite number", num);
    }
  }
}
```


### テストスタブ

```c
int isPrimeNumber(int num) {
  return (num == 2) || (num == 3) || (num == 5) || (num == 7);
}
```


このテストスタブは与えられた値が素数かどうかを判定するプログラムとしては明らかに不完全であるが、テストドライバから実行する範囲においては正しい挙動を示すので、指定した範囲でのテストスタブとしては十分な場合がある。しかし実行範囲が変わったときに直し忘れる可能性があるため、テストスタブ名に実行範囲を示す文字を入れる場合がある。

## 回帰試験 (Regression Test)

プログラムを修正・変更した場合に、過去に実施したテストを再度実施することを回帰試験 (英: regression test) 又は退行テストという。修正前の試験に再度合格するかどうか、他の機能に影響与えていないかどうか、他の機能が動作するかどうかを確認する。過去のテスト資産を使い、実施する回数も多いことから、実施を省略することがないようにテスト自動化することにより効率化を図る。

回帰試験にて、テストする範囲を全テストケースとするか、(全テストケースを実施した場合に要する時間や工数と修正が及ぼす範囲を考慮して)部分テストケースとするか判断し、また、欠陥を検出する頻度を考慮して高い優先度で実施するテストケースを選択する方法がある。

### 再現試験 (Repeatability Test)
再現試験 (repeatability test) は、初めて起きた現象・実験結果を確認する追試と、事故・不具合を再現し対策を立てるために実施することがある。

## 統計的手法
ソフトウェアが複雑になり、機能、関数の数が千以上になってくると、性能試験、機能試験の結果を統計的に処理し、どういう試験を実施するとよいかを統計的に検討することがある。また、テストでは、欠陥が存在することを示すことはできるが、欠陥が存在しないことは証明できないため、いつソフトウェアテストを終了すればよいかを決定するための基準として統計的手法として信頼度成長曲線等を利用する場合がある。信頼度成長曲線を利用する場合には、条件の変化を統計的にうまく扱わないと見落としが発生するか、無駄な作業を続けることがある。

## アジャイルテストの4象限
アジャイルテストの4象限とは、テストを「ビジネス面/技術面 x チーム支援/製品の批評」の4象限に分類したものである。例えば単体テストは特定モジュールという技術要素に着目しチームの開発を支援する目的で設定されるテストであり「技術面 x チーム支援」の第1象限に分類される。アジャイルテストの4象限という分類により、各テストが持つ役割を明確に認識することが可能になる。

## 脚注

### 注釈

### 出典


## 関連項目

## 関連ツール
* xUnit - コンピュータプログラムの単体テストツール
* JUnit - Javaプログラムの単体テストツール
* TestNG - Javaのためのテスティングフレームワーク
* QualityForward - 複数拠点、チーム単位でのテスト管理・分析が可能なクラウド型テスト管理ツール
* Qangaroo - Web上でExcelライクなインターフェースを有するシンプルで直感的な作業を可能とするクラウド型テスト管理ツール
* TestLink - オープンソースのテスト管理システム
* TESTRUCTURE - テスト設計プロセスを支援するテスト設計ツール
* CAT - テスト設計プロセスを支援するテスト設計ツール