ソフトウェアテストの目的と定義

こんにちは、株式会社ROI開発部です！
今回は本開発部にて勉強会を実施しました、ソフトウェア開発におけるテスト手法について、投稿をさせていただきます。

# 経緯
本開発部では、開発品質向上の施策を検討する定例会を、隔週で実施しています。
そこで下流工程の品質向上について議論が行われた際、まずはテスト工程の改善から始めようという話になりました。

いざ改善を始める前に、
　「そもそもソフトウェア開発におけるテストの目的や定義は何か再確認しよう！」
　「テストに関する認識を共有したうえで議論をはじめよう！」
ということでテスト手法に関する勉強会を実施しました。

今回はその内容について投稿させていただきます。

# 目的
- ソフトウェアテスト(以降、テスト)に関する認識を共有する。
- テスト工程を見直し、より品質の高い開発を行うための足掛かりにする。

# テストの種類
## テストの手法に関するワード
- ホワイトボックステスト
- ブラックボックステスト

## テストの種類に関するワード
### 実行方法によるテストの分類
- 動的テスト
    - テスト対象のソフトウェアテストを<font color="red"><b>動かして</b></font>行うテスト。
        - 機能テスト
        - 性能（負荷）テスト
        - ユーザービリティテスト
        - セキュリティテスト
- 静的テスト
    - テスト対象のソフトウェアテストを<font color="red"><b>動かさずに</b></font>行うテスト。
        - コードレビュー
        - ツールによる静的解析（CheckStyle、FindBugs等）

### 品質の観点による分類（動的テストをさらに分類）
- 機能テスト
    - 機能が正しく実装されているかのテスト。
        - 単体テスト
        - 総合（結合）テスト
        - システムテスト
        - 受入テスト
- 性能（負荷）テスト
    - ソフトウェアの実行速度、負荷耐性に関するテスト。
- ユーザービリティテスト
    - （ユーザーにとっての）ソフトウェアの使いやすさに関するテスト。
- セキュリティテスト
    - 外部からの攻撃に対するテスト。

### 工程（誰がテストするか）による分類（機能テストをさらに分類）
- 開発側が行うテスト
    - 単体テスト
    - 総合（結合）テスト
    - シナリオテスト
- 顧客側が行うテスト
    - 受入テスト

# テストの技法（ホワイトボックステスト/ブラックボックステスト）
## ホワイトボックステスト
- ソフトウェアの<font color="red"><b>内部構造を見て</b></font>、論理構造の正しさをテストする。
    - 各行、各ブロックで実行される文は正しく書かれているか。
    - 条件分岐（if文、switch文）の条件は適切か。
    - 終了まで実行されるか。
- ソフトウェアの内部構造に着目することで、ソフトウェアが<font color="red"><b>設計通り</b></font>に動作するかを検証することができる。
- （おまけ）テストにより算出された<font color="red"><b>カバレッジ率</b></font>（ソフトウェアがテストされた割合）が、ソフトウェアの品質の指標の1つになっている。xUnitにカバレッジ率を測定する機能が搭載されていたりする。

## ブラックボックステスト
- ソフトウェアの<font color="red"><b>内部構造を見ずに</b></font>、様々な入力パターンに対する出力の正しさをテストする。
- 入力と出力のみに着目することで、ソフトウェアが<font color="red"><b>仕様通り</b></font>に動作するかを検証することができる。

## 各テストでのテスト例
### 例題
- 入力された2つの数字を掛け算して、計算結果を出力するソフトウェアをテストする。

### ホワイトボックステストでのテスト例
- 入力チェックのテスト
    - 入力されたのは数字か？
- 条件分岐のテスト
    - 数字が入力された場合、掛け算の計算が実行されるか？
    - 数字以外が入力された場合、エラー処理が実行されるか？
- 出力処理のテスト
    - 掛け算の結果を出力しているか？

### ブラックボックステストでのテスト例
- 「8」と「4」の2つの数字を入力した場合、「32」と出力されるか？<br>（具体的な数字のパターンをテストする）
    - ソフトウェア内部で以下のいずれの方法で計算していても、テストNGとはならない。（テストの観点として見ていない）
        - 8×4 = 32（想定される計算）
        - 4×8 = 32（数字を逆にして計算）
        - 8+8+8+8 = 32（「8」の数字を「4」回足し算する）
- 数字以外の文字を入力した場合、エラーが出力されるか？

## どちらのテストを行うべきか？
- それぞれ<font color="red"><b>目的（仕様 or 設計）</b></font>が違うので優劣はない。目的に応じたテストをすべき。
- 以下の図のように、テストする観点（ユーザー要求 or 故障や欠陥）や対象（要件/仕様 or 設計/実装）で選択すると良い。
![ブラックorホワイトの指標.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531245/046585ab-e11b-37c1-16a2-e18c7ca2f3a9.jpeg)

- 流行の観点で見ると、アジャイル開発の流行に伴い、<font color="red"><b>テスト駆動開発（TDD）</b></font>という形でホワイトボックステストが採用されるケースが増加している。

# 各機能テストの説明
- 各機能テストを以下の観点で説明します。
    - 目的
    - テストの担当者
    - テストの実施方法
    - ホワイトボックステスト、ブラックボックステストのどちら（または両方）を行うか。

## 単体テスト
- 目的
    - ソフトウェアを構成する最小の要素（単体）に対するテスト。設計通りに実装されているかをテストする。
- テストの担当者
    - （ソフトウェアを作成した）開発者が行う。
- テストの実施方法
    - xUnitを用いてテストケースを作成する。
    - デバッガを用いる。
- ホワイトボックステスト or ブラックボックステスト
    - 内部構造の正しさをテストするのが目的であるため、基本的にホワイトで行う。
    - ブラックは必要に応じて実施する。<br>（早期に仕様の齟齬をなくしたい、開発スピードの短縮など）

## 総合（結合）テスト
- 目的
    - 同一機能内の単体の組み合わせ（内部結合）、または異なる機能間の組み合わせ（外部結合）に対して、機能連携が正しく行われることをテストする。
- テストの担当者
    - （ソフトウェアを作成した以外の）開発者がテストを行う。
- テストの実施方法
    - 運用時と同じく画面等からソフトウェアを実行する。<br>（連携先が未完成ならドライバ、スタブ等を作成する）
    - xUnitを用いてテストケースを作成する。
- ホワイトボックステスト or ブラックボックステスト
    - 画面からの操作など一連の流れをテストする場合はブラックボックステスト。
    - ロジック間の連携をテストする場合はホワイトボックステスト。

## シナリオテスト
- 目的
    - ソフトウェアの全機能に対するテスト。
    - 実際の運用を想定したシナリオを作成し、仕様通りにソフトウェアが作成されているかをテストする。
- テストの担当者
    - （ソフトウェアを作成した以外の）開発者がテストを行う。
- テストの実施方法
    - 運用時と同じ画面等からテストを行う。
- ホワイトボックステスト or ブラックボックステスト
    - 実際の運用を想定し、仕様面での正しさをテストするのが目的であるため、ブラックでテストする。

## 受入テスト
- 目的
    - 顧客が納品されたソフトウェアに対して、仕様通りに作成されているかをテストする。
    - 自社開発の場合は行われない場合が多い。
- テストの担当者
    - 顧客がテストを行う。
- テストの実施方法
    - 運用時と同じ画面等からテストを行う。
- ホワイトボックステスト or ブラックボックステスト
    - 実際の運用を想定し、仕様面での正しさをテストするのが目的であるため、ブラックでテストする。

## 補足（質問事項）
- Q1：単体テストと総合（結合）テストの定義が曖昧ですが、テストを分類する指標はありますか？
    - テストの手法についてまとめた書籍や技術記事でも定義が曖昧です。逆説的に開発チームごとにどのようにテストの分類を定義することが重要となります。
- Q2：ユーザービリティテストはどのように行いますか？
    - 実際に使ってもらい、使いやすさのアンケートを取るなどして、改善点を見出すなどの方法があります。
- Q3：負荷テストはどのように行いますか？
    - 負荷耐性のテストはJmeter等のツールでシナリオを作成して行うのが一般的です。
- Q4：総合（結合）テストやシナリオテストは、ソフトウェアを作成した以外の開発者が行うとあるが、実際にそのようにテストを行うのは可能ですか？
    - 教科書的にはソフトウェアを作成した以外の開発者が行うべきとなっていますが、実態としては、テスト専任のチームが編成できるような開発体制でないと難しいと思われます。
- Q5：今回はテスト手法のおさらいするということで、古くから行われているテスト手法の説明がされていましたが、最近登場した新しいテスト手法やどの企業でどういうテストを採用しているかといった情報はありますか？
    - 最近だとテスト駆動開発（TDD）などのテスト手法などが人気ですが、他に流行しているテスト手法や企業での導入事例について、別途調べてまとめてみます。（宿題）

# 参考文献
- 知識ゼロから学ぶソフトウェアテスト【改訂版】
    - 著者：高橋 寿一
    - 出版社：翔泳社
- ソフトウェアテスト入門 押さえておきたい《要点・重点》
    - 著者：ソフトウェアテストPRESS編集部
    - 出版社：技術評論社

以上です。