ソフトウェアテストってなんだろう？

# テストとは
>JSTQB（テスト技術者資格）のシラバスより

ソフトウェアテストはソフトウェアの品質を評価し，運用環境でソフトウェアの故障が発生するリスクを低減する1つの手段である．

# ソフトウェアの品質
> ソフトウェア品質の評価に関する国際規格(ISO/IEC 9126) より

- **機能性（functionality）** - 機能とその特性に影響する特性群．機能には，必要性を明確に述べているものと暗に示しているものがある
- **信頼性（reliability）** - ある状況がある時間続いたときにソフトウェアがどの程度機能するかに影響する特性
- **使用性（usability）** - 利用するのにかかる手間，個人の努力などに影響する特性
- **効率性（efficiency）** - ソフトウェアの性能やそれに要するリソース量に影響する特性
- **保守性（maintainability）** - 何らかの変更を加えるのにかかる手間に影響する特性
- **移植性（portability）** - 別の環境にソフトウェアを移行させる可能性に影響する特性

つまり，テストとは，ここにあげてあるような6つの特性を評価して，運用で不具合が起きないようにするための手段である．

具体例として以下のような観点で評価すると良い．
- ボタンを押したら入力した内容が登録されるか **（機能性(機能要件)）**
- 画面遷移したときに異常に待たされたりしないか **（機能性(非機能要件))**
- ボタンが押しにくくないか，エラーメッセージがわかりやすいか **（使用性）**

:::note info
**機能要件**
ソフトウェアやシステム開発において，クライアントから求められる機能
- **ユーザー登録機能:** 新しいユーザーがアカウントを作成できる機能
- **ログイン機能:** 既存ユーザーが認証を通じてシステムにアクセスできる機能
- **パスワードリセット機能:** ユーザーがパスワードを忘れた場合にリセットできる機能
- **プロフィール編集機能:** ユーザーが自分のプロフィール情報を更新できる機能
- **商品検索機能:** ユーザーが商品を検索できる機能
- **商品詳細表示機能:** 選択した商品の詳細情報を表示する機能
- **カート機能:** ユーザーが購入したい商品をカートに追加、確認できる機能
- **注文機能:** ユーザーがカート内の商品を購入するための機能
- **管理者用ダッシュボード:** 管理者がシステム全体の状況を把握できるダッシュボード機能
- **ユーザー管理機能:** 管理者がユーザーの情報を管理できる機能
- **商品管理機能:** 管理者が商品の情報を管理できる機能
- **注文管理機能:** 管理者が注文の状況を管理できる機能

**非機能要件**
機能要件以外のユーザービリティ，性能，拡張性，セキュリティなどの品質的に関連するもの全般
- **パフォーマンス:** システムの応答時間や処理能力に関する要件。1秒以内にページロード，1000リクエスト/秒に対応できる
- **セキュリティ:** システムの安全性に関する要件．HTTPS対応，CSRF対策，SQLインジェクション対策，XSS対策
- **可用性:** システムの稼働率や障害対応に関する要件．99.9%の稼働率，障害発生時の自動復旧
- **拡張性:** システムの将来的な拡張に関する要件．将来的な機能追加に対応できる柔軟な設計
- **保守性:** システムの保守や管理のしやすさに関する要件．コードの可読性，ドキュメントの整備，自動テストの導入
- **ユーザビリティ:** ユーザーの使いやすさに関する要件．シンプルで直感的なUI，アクセシビリティ対応，レスポンシブデザイン
:::

# テストの分類

テストには目的によっていろんな種類がある．いろんな種類のテストを組み合わせて品質を確保するのが大事である．具体的には以下のような分類方法がある．

- テストのフェーズ
- テストの手法
- テストの技法・考え方


## テストのフェーズでの分類

フェーズによる分類とは，細かいものからフェーズごとにテストすることである．

- 単体テスト
  メソッド単位やクラス単位でのテスト
- 統合テスト
  メソッドやクラスを組み合わせた機能単位でのテスト
- システムテスト
  システム全体としての挙動のテスト
- 受け入れテスト
  対向システムとの連携なども含めたユーザ運用に則したテスト

ソフトウェア設計とソフトウェアテストは以下のような関係になっている
![スクリーンショット 2024-07-04 22.15.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/cfc4f6bd-6050-1084-c988-e5dd7c7c1cb4.png)

それぞれどこを設計，テストしているかを表した図は以下の通りである．
![スクリーンショット 2024-07-04 22.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/38f7ea6c-1303-ecb3-c749-c1d032436e39.png)

## テストの手法での分類

- 手動テスト
  文字通り手を動かして画面の操作やAPIの実行を行うテスト
- 自動テスト
  ツールやプログラムを駆使して自動で行うテスト

最近では，自動テストを構築し，CI/CDを利用して早期に不具合を検出する開発手法が一般的になっている．しかし，自動テストは単純に手動テストを自動化するものではなく，専用のテスト設計が必要．また，「自動テストは手動テストよりもコストがかからない」という考えも必ずしも正しくない．自動化のための初期コストや，テストのメンテナンスにかかるランニングコストが存在するためである．したがって，プロジェクトの状況に応じて適切なテスト手法を選ぶことが重要．


## テストの技法・考え方での分類

### ホワイトボックステスト

実装を把握したうえでそのコードの中身を評価するテスト．テストコードを書いてユニットテスト（単体テスト・コンポーネントテスト）をするような手法．

長所：実装に則した網羅的テストが可能
短所：仕様に書いてあるけど実現が漏れているような部分がテストできない

ホワイトボックステストでは以下にケースを網羅する．

- 処理網羅(C0網羅)
  それぞれの命令文が少なくとも1回は実行されるようにテストする
- 分岐網羅(C1網羅)
  それぞれの判定条件における真偽が少なくとも1回は実行されるようにテストする
- 条件網羅(C2網羅)
  それぞれの条件文における真偽が少なくとも1回は実行されるようにテストする


:::note info
**網羅の例**
![スクリーンショット 2024-07-04 23.33.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/ecc38e50-00b6-f22a-2485-0c979bdc11c2.png)


**処理網羅**
プログラムの命令が正常に実行されることをテスト
 - テストデータ：X=1とY＝1
 - テスト項目：命令1，命令2

**分岐網羅**
プログラムの条件分岐が正常に実行されることをテスト
- テストデータ：X＝1とY＝1，X＝2とY=2
- テスト項目：分岐1と分岐3，分岐2と分岐4

**条件網羅**
分岐の組み合わせ経路が正常に実行されることをテスト
- テストデータ：X＝1とY＝1，X＝1とY＝2，X＝2とY＝1，X＝2とY=2
- テスト項目：分岐1→分岐3，分岐1→分岐4，分岐2→分岐3，分岐2→分岐4

:::


### ブラックボックステスト

実装を意識せず仕様をベースに評価するテスト．

長所：ユーザの立場からのテストが可能，実装漏れや考慮漏れに気づきやすい
短所：コードの中で特殊なことを行ってるような処理のテストが困難

ブラックボックステストでよくつかわれる考え方・技法：

- 境界値分析
  条件の切り替わる境界に注目してケースを分ける
- 同値分割
  同じ処理になるケースは1つにまとめる
  
:::note info
**境界値分析**
入力値inpが「0以上64未満」という仕様であるとき，
 - 0
 - 1
 - 64
 - 65
 
の4パターンをテストする．

**同値分割**
ユーザーログインのユーザー名とパスワードについて
- 同値クラス1: 空のユーザー名、パスワード
- 同値クラス2: 適切な長さのユーザー名とパスワード
- 同値クラス3: 適切な長さだが不正な文字を含むユーザー名とパスワード
- 同値クラス4: 適切な長さのユーザー名とパスワード、ただしユーザー名が存在しない

:::

- デシジョンテーブル
  条件の組み合わせを書き出して各パターンごとにテストする

:::note info
**デシジョンテーブルの例**
- 初期値: 0
- 足し算命令：+10
- 引き算命令：-10
- 掛け算命令：x10
- 足し算→引き算→掛け算の優先度とする

このとき，この計算をテストしようと思ったら，
以下のようにデシジョンテーブルを書くと必要なテストケースを整理しやすい．

| 条件 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|------|---|---|---|---|---|---|---|---|
| 足し算命令：+10 | ○ | ○ |  | ○ |   |   | ○ |   |
| 引き算命令：-10 | 　 | ○ |  ○ |   |  | ○ | ○ |   |
| 掛け算命令：x10 | ○ |   | ○ |   | ○ |   | ○ |   |
| 最終的な計算結果 | 100 | 0 | -100 | 10 | 0 | -10 | 0 | 0 |
:::



### 探索的テスト

あらかじめテストケースを作るのではなく，システムの挙動やそれまでのテスト結果を見ながらバグが潜んでそうな処理やテストが不十分そうな機能に絞って集中的に動かしてみるテスト．

:::note info
意図的にあり得ない操作や想定外の入力で想定外のバグを見つけられるかもしれない．いわゆるゲームのデバッグにおいて壁にハマるバグを見つける際に想定外の操作によって見つかる，といったものだ．
:::


### シナリオテスト

システムを利用するユーザーの運用シナリオでシステムの挙動を確認するテスト．正しいデータで運用ができることの確認として検証の終盤で実施されることが多い．

### 回帰テスト

プログラムの一部分を変更した際にほかの箇所に不具合が出ていないかを確認するためのテスト．リリース後のシステムに対して追加機能開発などの際に行う．

:::note info
システムが大規模で複雑になると，何も関係がないかのように見えるプログラムが相互に関係しあっているのを見落としてしまうことがある．その結果改修した結果思わぬところがうかくいかなかったりする，といったことも少なくないので，プログラムの変更部分のテストと回帰テストはセットで実施することが望ましい．
:::