はじめに
ソフトウェアテストを学び始めると、単体テスト、結合テスト、システムテスト、E2Eテスト、回帰テストなど、似た言葉が一度に出てきます。
さらに、同値分割や境界値分析といったテスト技法、テストピラミッド、カバレッジ、CI/CDまで並ぶと、それぞれが何を表しているのか分からなくなりがちです。
この記事では、手書きの学習メモをもとに、次の内容を一つの流れで整理します。
- V字モデルとISTQBの5つのテストレベル
- レビュー・静的解析と動的テストの違い
- ブラックボックステストとホワイトボックステスト
- 同値分割、境界値分析、組合せテスト
- テストピラミッドとE2Eテストの位置づけ
- 手動テスト、非機能テスト、セキュリティテスト
- スモークテスト、修正確認テスト、回帰テストの違い
- 探索的テスト、モンキーテストなど現場で使われるテスト名
- CI/CDでテストを実行する方法
- テスト自動化で気をつけたいこと
pytestのサンプルとGitHub Actionsの設定例も載せるため、用語を覚えるだけでなく、手元で動かしながら確認できます。
先に結論
ソフトウェアテストは、テストの名前を暗記するより、次の5つを分けて考えると理解しやすくなります。
| 分ける観点 | 確認する問い | 例 |
|---|---|---|
| テストレベル | どの範囲を確認するか | コンポーネント、コンポーネント統合、システム、システム統合、受け入れ |
| テスト技法 | テストデータをどう選ぶか | 同値分割、境界値分析、ペアワイズ |
| テストタイプ | 何を根拠にどの特性を確認するか | 機能、非機能、ブラックボックス、ホワイトボックス |
| 変更に伴うテスト | 修正とその影響をどう確認するか | 修正確認テスト、回帰テスト |
| 実行方法・タイミング | 誰が、いつ、どう実行するか | 手動、自動、CI、定期実行 |
例えば、回帰テストは「単体テストの上位にあるテストレベル」ではありません。変更による悪影響がないかを確認するテストで、コンポーネントから受け入れまで、必要なテストレベルで行えます。
CIもテストの種類ではありません。コード変更を継続的に統合し、ビルドやテストを自動実行する仕組みです。
前提
- 対象読者: ソフトウェアテストを体系的に学びたい初心者、開発現場でテスト用語を整理したい人
- サンプル環境: Python 3、pytest、pytest-cov、GitHub Actions
- UIテストの例: PlaywrightのPage Object Model
- 扱う範囲: 基本的なテスト設計、自動化、CI/CDでの実行
- 扱わない範囲: 特定組織の品質保証規定、負荷試験基盤の詳細、侵入テストの具体的な攻撃手順
- 仕様確認日: 2026-08-15
テストには静的テストと動的テストがある
テストは、プログラムを実行して確認する作業だけではありません。成果物を実行せずに確認する静的テストと、実際にコードを動かす動的テストに分けられます。
| 分類 | 実行の有無 | 例 | 見つけやすい問題 |
|---|---|---|---|
| 静的テスト | テスト対象のコードを実行しない | 要件レビュー、設計レビュー、コードレビュー、静的解析 | 要求の矛盾、設計漏れ、規約違反、危険な実装 |
| 動的テスト | テスト対象のコードを実行する | コンポーネントテスト、統合テスト、システムテスト | 計算間違い、連携エラー、性能不足、実行時の不具合 |
要件定義書の曖昧さをレビューで見つければ、実装後に大きく作り直すよりも早く対応できます。静的テストと動的テストは代替関係ではなく、両方を組み合わせます。
V字モデルで開発とテストの対応を見る
V字モデルは、開発工程と、それぞれの成果物を確認するテスト工程の対応を表す考え方です。
図をスマートフォンでも追いやすくするため、V字の左右配置ではなく、開発成果物と対応するテストを縦に並べています。
代表的な対応は次のとおりです。
| 開発側の成果物 | 対応するテスト | 主に確認すること |
|---|---|---|
| 詳細設計、コンポーネント設計 | コンポーネントテスト | 関数、クラス、モジュールが単独で意図どおり動くか |
| コンポーネント間のインターフェース設計 | コンポーネント統合テスト | モジュール、内部API、DBアクセスの連携が正しいか |
| システム要件 | システムテスト | システム全体が機能要件・非機能要件を満たすか |
| 外部システム・外部サービス間のインターフェース設計 | システム統合テスト | 決済、通知、他システムとの連携が正しいか |
| 利用者・業務の要求 | 受け入れテスト | 実際の業務で利用でき、要求を満たすか |
実際の工程名と対応関係は組織によって変わります。V字モデルは工程を固定するためではなく、「この設計内容を、どのテストで確認するのか」を早い段階で考えるために使います。
テストは実装後に初めて考えるものではありません。要件定義や設計の段階で受け入れ条件とテスト観点を作ると、曖昧な要求を早く見つけられます。
ISTQBの5つのテストレベルを具体例で整理する
ECサイトで商品を注文する機能を例にします。
日本の開発現場では、「単体・結合・システム・受け入れ」の4区分で呼ぶこともあります。この場合の「結合テスト」は、ISTQB CTFL v4.0.1のコンポーネント統合テストとシステム統合テストをまとめて指す場合があります。名前だけで判断せず、テスト対象と目的を確認します。
コンポーネントテスト(単体テスト)
コンポーネントテストは、関数、クラス、モジュールなどをできるだけ分離し、小さな単位の振る舞いを確認します。Unit Test、Component Test、単体テストと呼ばれることがあります。
確認例:
- 5,000円以上なら送料が0円になるか
- 在庫数を超える注文を拒否するか
- 不正な金額を渡したときに例外になるか
- 条件分岐の各経路を通るか
JUnit、PHPUnit、Pythonのunittestやpytestなどは、テストの実行、結果の判定、前処理・後処理を支えるテストフレームワークです。
テストハーネスという言葉は、テストフレームワークだけでなく、テストデータ、スタブ、ドライバー、実行スクリプト、レポートなどを含むテスト実行環境全体を指す場合があります。
コンポーネント統合テスト
コンポーネント統合テストは、システム内部の複数コンポーネントをつないだときのインターフェースと相互作用を確認します。
確認例:
- 注文サービスがリポジトリ層を通じてDBへ保存できるか
- 在庫コンポーネントと注文コンポーネントのデータ形式が合っているか
- 下位コンポーネントのエラーを上位層が正しく処理できるか
テストダブルに置き換える範囲と、テスト用DBなどの実物で確認する範囲を、テスト目的に応じて決めます。
システムテスト
システムテストは、統合済みのシステム全体が要件を満たすか確認します。
機能だけでなく、次のような非機能要件も対象になります。
- 応答時間や同時利用数を確認する性能テスト
- 障害や通信断からの回復を確認する信頼性テスト
- 対応ブラウザや外部システムとの連携を確認する互換性・相互運用性テスト
- 操作の分かりやすさを確認するユーザビリティテスト
- 権限や入力値の扱いを確認するセキュリティテスト
システム統合テスト
システム統合テストは、テスト対象のシステムと、外部システムや外部サービスとのインターフェースを確認します。
確認例:
- 決済サービスの応答を受けて注文状態を更新できるか
- 外部サービスのタイムアウトやエラー応答を正しく処理できるか
- 外部APIのリクエスト・レスポンス形式が契約と合っているか
- 通知サービスやメッセージキューと正しく連携できるか
外部サービスをすべてモックにすると、認証、TLS、ネットワーク、実際のレスポンスといった接続差異を見逃します。契約テスト、検証環境、スタブを目的に応じて組み合わせます。
受け入れテスト
受け入れテストは、利用者や業務の視点で、要求を満たしているか確認します。
User Acceptance Test(UAT)は、利用者受け入れテストのことです。例えば、業務担当者が実際の注文手順に近い操作を行い、業務を継続できるかを判断します。
受け入れテストは「画面を人が触るテスト」とは限りません。契約上の受け入れ条件、法令・規制、運用受け入れなど、目的に応じた種類があります。
E2Eテストとシステムテストは同じではない
E2EはEnd to Endの略で、利用開始から目的達成までの一連の流れを確認する考え方です。
注文機能なら、次のような流れです。
ブラウザを使うE2Eテストはよくありますが、E2EとUIテストは完全な同義語ではありません。APIやメッセージングを含む業務フローを、UIを使わずに確認することもあります。
また、システムテストはシステム全体を要件に照らして確認するテストレベルです。E2Eは開始から終了までの経路に注目したテストの切り口です。現場で呼び方が曖昧な場合は、名前だけで判断せず、対象範囲と目的を確認します。
ブラックボックステストとホワイトボックステスト
ISTQB CTFL v4.0.1では、機能テスト、非機能テスト、ブラックボックステスト、ホワイトボックステストをテストタイプとして整理しています。ブラックボックスとホワイトボックスは、何を根拠にテストを作るかが異なります。
| 観点 | ブラックボックステスト | ホワイトボックステスト |
|---|---|---|
| テストの基準 | 仕様、入出力、利用者の操作 | コード構造、条件分岐、処理経路 |
| 内部実装の知識 | 必須ではない | 必要 |
| 見つけやすい問題 | 仕様との差、入力の扱い、機能の不足 | 通っていない分岐、到達しない処理、ロジックの誤り |
| 主な技法 | 同値分割、境界値分析、デシジョンテーブル | ステートメントカバレッジ、ブランチカバレッジ |
どちらか一方で十分という関係ではありません。仕様から考えるテストと、実装構造から考えるテストを組み合わせます。同値分割や境界値分析はブラックボックステストのテストケースを導く技法、ステートメントテストやブランチテストはホワイトボックス側の技法です。
テストデータを選ぶ3つの基本技法
すべての入力値と組合せを試すことは現実的ではありません。そのため、欠陥を見つけやすい値を選ぶ技法を使います。
同値分割
同値分割は、同じように処理されると考えられる入力値をグループに分け、各グループから代表値を選ぶ技法です。
5,000円以上で送料無料になる処理なら、次のように分けられます。
| 同値パーティション | 入力例 | 期待結果 |
|---|---|---|
| 不正な金額 | -1円 | エラー |
| 0円以上5,000円未満 | 3,000円 | 送料500円 |
| 5,000円以上 | 8,000円 | 送料無料 |
境界値分析
境界値分析は、同値パーティションの境界付近を重点的に確認する技法です。
条件が「5,000円以上」なら、4,999と5,000が重要です。不正値との境界も含めるなら、-1と0も確認します。
サンプルは次の構成で作成します。app/__init__.py は空ファイルです。
.
├── app
│ ├── __init__.py
│ └── shipping.py
├── tests
│ └── test_shipping.py
├── requirements-dev.txt
└── .github
└── workflows
└── test.yml
# テストの実行に使う
pytest
# Pythonコードのカバレッジを計測する
pytest-cov
def calculate_shipping_fee(subtotal: int) -> int:
"""注文金額に応じて送料を返す。金額は0円以上を前提とする。"""
if subtotal < 0:
# 不正な入力を計算結果として扱わず、呼び出し側へ知らせる
raise ValueError("subtotal must be zero or greater")
# 5,000円以上は送料無料とする
if subtotal >= 5_000:
return 0
return 500
import pytest
from app.shipping import calculate_shipping_fee
@pytest.mark.parametrize(
("subtotal", "expected_fee"),
[
(0, 500), # 不正値との境界: 最小の有効値
(1, 500), # 有効な通常値
(4_999, 500), # 送料無料になる直前
(5_000, 0), # 送料無料になる境界
(10_000, 0), # 送料無料側の通常値
],
)
def test_calculate_shipping_fee(subtotal: int, expected_fee: int) -> None:
assert calculate_shipping_fee(subtotal) == expected_fee
def test_negative_subtotal_is_rejected() -> None:
# -1は無効な値との境界として確認する
with pytest.raises(ValueError):
calculate_shipping_fee(-1)
実行方法は次のとおりです。
# テストとカバレッジ計測用の依存関係をインストールする
python -m pip install -r requirements-dev.txt
# 条件分岐のカバレッジも含めてテストする
python -m pytest --cov=app --cov-branch --cov-report=term-missing
パラメータ化した5ケースと負数の1ケースが成功すると、実行結果の末尾は次のようになります。実行時間は環境によって変わります。
============================== 6 passed in 0.XXs ==============================
カバレッジの表で app/shipping.py の未実行行が残っていないことも確認します。ただし、100%になっても仕様漏れや期待結果の誤りまでは検出できません。
ペアワイズ法
ペアワイズ法は、複数パラメーターのすべての値の組を総当たりする代わりに、任意の2因子の値の組が少なくとも一度は現れるよう、テストケースを絞る組合せテスト技法です。
例えば、次の組合せを考えます。
- OS: Windows、macOS、Linux
- ブラウザ: Chrome、Edge、Firefox
- 権限: 管理者、一般利用者
- 言語: 日本語、英語
総当たりでは3 × 3 × 2 × 2 = 36ケースです。ペアワイズ法を使うと、2因子間の組を保ちながらケース数を減らせます。
ただし、ペアワイズ法ですべての欠陥が見つかるわけではありません。3因子以上の組合せや、特定の業務条件が重要なら、そのケースを追加します。
「2因子の組合せで欠陥の何%を見つけられる」という数値を、すべてのシステムに共通する保証として使うことはできません。対象システム、過去障害、変更範囲、リスクを見てケースを追加します。
直交表も組合せを効率よく選ぶ方法ですが、ペアワイズ法と同じものではありません。直交表は水準の組合せを均衡させる性質を持ち、ペアワイズ法は2因子間の値の組を網羅することに注目します。
カバレッジは品質の証明ではない
カバレッジは、テストによってコードや条件をどこまで実行したかを表す指標です。
| 指標 | 確認すること |
|---|---|
| ステートメントカバレッジ | 実行可能な文をどれだけ通ったか |
| ブランチカバレッジ |
ifなどの分岐結果をどれだけ通ったか |
カバレッジが低ければ、通っていない処理を見つける手掛かりになります。しかし、カバレッジが100%でも、次の問題は残り得ます。
- 期待結果そのものが間違っている
- 要件の抜けをテストしていない
- 境界値や組合せが不足している
- 外部サービスとの接続差異がある
- 性能、セキュリティ、使いやすさを確認していない
カバレッジは「品質の点数」ではなく、テストの不足を探す観測値として使います。
テストピラミッドで自動化の配分を考える
テストピラミッドは、速く安定した小さなテストを多くし、遅く壊れやすい大きなテストを少なくする考え方です。
| 層 | 強み | 注意点 |
|---|---|---|
| 単体テスト | 速い、失敗箇所を特定しやすい、大量に実行しやすい | 外部サービスとの接続差異は分からない |
| API・結合テスト | コンポーネント間の契約やデータ連携を確認できる | 環境やテストデータの準備が必要になる |
| UI・E2Eテスト | 利用者に近い経路を確認できる | 遅い、失敗原因の切り分けが難しい、UI変更の影響を受けやすい |
UI・E2Eテストや手動テストばかりが増え、単体テストが少ない状態は「アイスクリームコーン」と呼ばれることがあります。この状態では確認に時間がかかり、変更のたびに人の作業が増えやすくなります。
ピラミッドの比率に絶対的な正解はありません。マイクロサービス、データ処理、組込み、画面中心のシステムでは、必要なテストの配分が変わります。
UIテストはPage Objectで変更箇所をまとめる
UIテストで、各テストケースにCSSセレクターと操作を直接書き続けると、画面変更のたびに多数のファイルを直すことになります。
Page Object Modelは、画面の要素と操作を一つのクラスへまとめる設計パターンです。テストケースは「ログインする」「注文する」といった利用者の操作に近い言葉で書けます。
import { type Locator, type Page } from "@playwright/test";
export class LoginPage {
private readonly emailInput: Locator;
private readonly passwordInput: Locator;
private readonly loginButton: Locator;
constructor(private readonly page: Page) {
// 画面要素の探し方をPage Objectへ集約する
this.emailInput = page.getByLabel("メールアドレス");
this.passwordInput = page.getByLabel("パスワード");
this.loginButton = page.getByRole("button", { name: "ログイン" });
}
async open(): Promise<void> {
await this.page.goto("/login");
}
async login(email: string, password: string): Promise<void> {
// テスト側へセレクターを漏らさず、利用者の操作として表現する
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.loginButton.click();
}
}
import { expect, test } from "@playwright/test";
import { LoginPage } from "../pages/login-page";
test("有効な利用者がログインできる", async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.open();
await loginPage.login("test@example.com", "example-password");
// 期待結果の判定はPage Objectではなくテスト側に置く
await expect(page.getByRole("heading", { name: "ダッシュボード" })).toBeVisible();
});
Seleniumの公式ドキュメントでも、Page Objectは重複を減らし、UI変更時の修正箇所を集約する方法として説明されています。Playwrightでも同じ考え方を使えます。
Page Objectを使っても、巨大な1クラスへすべてを詰め込むと保守しにくくなります。画面全体だけでなく、ナビゲーションや商品一覧など、再利用する部品をPage Componentとして分ける方法もあります。
スモークテスト・修正確認テスト・回帰テストの役割
| テスト | 目的 | 実行例 |
|---|---|---|
| スモークテスト | 詳細なテストへ進める最低条件を満たすか、短時間で確認する | アプリが起動する、ログインできる、主要APIが応答する |
| 修正確認テスト | 報告された欠陥が正しく修正されたか確認する | 元の再現手順と失敗したテストを再実行する |
| 回帰テスト | 変更によって既存機能が壊れていないか確認する | 修正箇所の周辺、主要業務、過去障害の再テスト |
スモークテストに失敗しているのに、時間のかかるE2Eテストをすべて実行しても、多数の失敗が同じ原因から発生する可能性があります。最初に短いテストで、テスト対象が確認可能な状態かを見ます。
欠陥修正後は、まず修正確認テストで元の不具合が解消されたかを確認します。次に影響分析を行い、変更の影響が及ぶ可能性のある範囲へ回帰テストを広げます。
回帰テストは変更のたびに繰り返すため、自動化と相性がよい領域です。ただし、変更によって確認すべき観点も変わるため、過去の自動テストを流すだけで終わらせません。
現場で耳にするテスト名を目的別に整理する
テストの名称は、すべてが同じ分類軸に並ぶわけではありません。「どの範囲を確認するか」「どのように操作するか」「何の品質を確認するか」など、異なる観点の呼び方が混在しています。
例えば、一つのテストが「E2Eテスト」であり、「回帰テスト」であり、「自動テスト」でもあることがあります。名前だけで判断せず、対象、目的、方法、合格条件を確認することが大切です。
操作やテストケースの作り方に関する名称
| 名称 | 簡単な説明 |
|---|---|
| 正常系テスト | 正しい入力と想定された手順で、期待する結果になるか確認する |
| 異常系テスト | 不正入力、権限不足、通信失敗などが起きても、安全に処理できるか確認する |
| 探索的テスト | 対象を学びながら、テストの設計・実行・評価を同時に進める |
| アドホックテスト | 詳細なテストケースを事前に作らず、経験や気づきをもとに確認する |
| チェックリストベースドテスト | 過去障害や重要観点をまとめたチェックリストに沿って確認する |
| モンキーテスト | ランダムまたは予測しにくい操作を与え、クラッシュ、停止、表示崩れなどを探す |
| ファズテスト(ファジング) | 不正・予想外・大量の入力データを自動投入し、異常終了や脆弱性につながる挙動を探す |
モンキーテストは、単に人が無計画に画面を触ることではありません。対象画面、操作回数、監視項目を決め、自動実行では乱数シードと操作ログを残すと、問題を再現しやすくなります。Androidの公式Monkeyツールも、疑似ランダムなユーザー操作を生成し、同じシードで操作を再現できる仕組みを備えています。
探索的テストも「思いつきで触るだけ」ではありません。目的を書いたテストチャーター、実施時間、操作記録、発見事項を残すと、自由度を保ちながら結果を共有できます。
品質特性や利用条件に関する名称
| 名称 | 簡単な説明 |
|---|---|
| 負荷テスト | 想定する利用者数やリクエスト数で、応答時間と処理能力を満たすか確認する |
| ストレステスト | 想定を超える負荷をかけ、限界、壊れ方、回復方法を確認する |
| 耐久テスト(ソークテスト) | 一定の負荷で長時間動かし、メモリリークや性能劣化が起きないか確認する |
| スパイクテスト | 短時間に負荷を急増・急減させ、追従と回復を確認する |
| 互換性テスト | 対象ブラウザ、OS、端末、外部サービスの組合せで動作するか確認する |
| ユーザビリティテスト | 利用者が迷わず、効率よく目的を達成できるか確認する |
| アクセシビリティテスト | キーボード操作、読み上げ、色の識別など、多様な利用条件で使えるか確認する |
| セキュリティテスト | 認証、認可、入力処理、機密情報の扱いなどに弱点がないか確認する |
| 回復性・フェイルオーバーテスト | 障害や通信断の後に復旧でき、必要に応じて待機系へ切り替わるか確認する |
負荷テストとストレステストは似ていますが、前者は主に想定範囲で性能目標を満たすか、後者は限界を超えたときの安定性と回復を確認します。アクセシビリティは自動ツールだけで判定できない項目もあるため、キーボード操作や支援技術を使った人による確認も組み合わせます。
手動テストをなくさない
自動化できるのは、期待結果を事前に定義し、機械が判定できるテストです。人が操作しながら気づきを探す探索的テスト、見た目や使いやすさの確認、まだ仕様が固まっていない機能には、手動テストの価値があります。
画面では、正常系の手順だけでなく次のような操作も確認します。
- ボタンを短時間に連続で押したとき、二重登録されないか
- 長い文章、絵文字、異体字、複数言語を入力しても表示が崩れないか
- 大きな画像や動画をアップロードしたとき、制限とエラーが分かりやすいか
- 通信が途中で切れたとき、再実行や復旧が安全か
- 対応対象のブラウザや画面サイズで操作できるか
- エラーメッセージを読んで、利用者が次の行動を判断できるか
SQLインジェクションやXSSなどのセキュリティテストは、通常の入力確認と同じ感覚で本番環境へ試してはいけません。対象、許可、時間帯、監視、データ復旧方法を決めた承認済み環境で、OWASP Web Security Testing Guideなどの手順を参考に行います。
権限のないシステムに攻撃文字列や大量リクエストを送ってはいけません。学習時は、自分が所有するローカル環境や、明示的に許可された検証環境だけを使ってください。
CI/CDでテストを段階的に実行する
CIはContinuous Integrationの略で、コード変更を頻繁に統合し、ビルドやテストを自動実行する考え方です。CDはContinuous DeliveryまたはContinuous Deploymentを指し、リリース可能な状態を保つ、または本番反映まで自動化する考え方です。
CIでテストに失敗した変更を止め、その後のデプロイへ進ませないようにすると、テストを品質ゲートとして使えます。CDまで含める場合は、テスト成功後に検証環境へデプロイし、必要な確認を通過した変更だけを本番リリースへ進めます。
テストとデプロイは、次のように段階を分けると運用しやすくなります。
次は、Pull Requestではテストだけを実行し、mainブランチへのPushではテスト成功後に検証環境へのデプロイジョブを実行する例です。
name: test-and-deploy-staging
on:
push:
pull_request:
permissions:
contents: read
jobs:
unit-test:
runs-on: ubuntu-latest
steps:
# リポジトリのコードを実行環境へ取得する
- name: Checkout source
uses: actions/checkout@v6
# プロジェクトで使うPythonを準備する
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
# 依存関係とテストツールをインストールする
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements-dev.txt
# 単体テストとブランチカバレッジを確認する
- name: Run tests
run: |
python -m pytest --cov=app --cov-branch --cov-report=term-missing
deploy-staging:
# テストが失敗した場合はデプロイへ進めない
needs: unit-test
# Pull Requestでは実行せず、mainブランチへのPushだけを対象にする
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
steps:
- name: Checkout source
uses: actions/checkout@v6
- name: Deploy to staging
run: |
# 実際には組織で承認されたデプロイコマンドへ置き換える
echo "Run the staging deployment command here"
needs: unit-testにより、テストが失敗するとdeploy-stagingは実行されません。ifは、Pull Requestの作成・更新時にはデプロイせず、mainへのPushだけを対象にする条件です。environment: stagingを指定しておくと、GitHubのEnvironmentへ登録した検証環境用のシークレットや保護ルールを利用できます。
この例のデプロイ処理はechoだけであり、そのままでは環境へ反映されません。実際には、AWS、GCP、コンテナ基盤など、組織で承認されたデプロイコマンドへ置き換えます。本番デプロイは、検証環境でのテスト結果、承認の要否、ロールバック手順を決めてから追加します。
実務では、失敗したテストのログ、スクリーンショット、トレース、テストレポートを成果物として保存すると、原因を調べやすくなります。外部サービス用の秘密情報はリポジトリへ直接書かず、GitHub ActionsのSecretsやOIDCなど、組織で承認された方法を使います。
テスト自動化研究会の「テスト自動化の8原則」
初稿では、手書きの学習ノートをもとに、8項目を「実務ルール」として再構成していました。しかし、ノート作成時の出典を記録できておらず、原典と独自整理の境界が不明確でした。
改めて確認したところ、ノートの内容は、テスト自動化研究会が公開している「テスト自動化の8原則」と対応していました。
次の表の左列は、テスト自動化研究会「テスト自動化の8原則」に掲載されている原則名をそのまま示しています。右列は原文の転載や要約ではなく、各原則を踏まえて筆者が追加した実務上の確認観点です。
| テスト自動化研究会の原則名(原文) | 筆者の実務上の補足 |
|---|---|
| 1. 手動テストはなくならない | 探索的テストや使いやすさの評価など、人の観察と判断を残す範囲を決める |
| 2. 手動でおこなって効果のないテストを自動化しても無駄である | テスト分析、テスト設計、期待結果を確認してから自動化対象を選ぶ |
| 3. 自動テストは書いたことしかテストしない | 合否判定に入れていない表示崩れや違和感は、人による別の確認で補う |
| 4. テスト自動化の効用はコスト削減だけではない | 変更へのフィードバック速度と、同じ確認を再現できる価値も評価する |
| 5. 自動テストシステムの開発は継続的におこなうものである | 対象システムの変更、実行時間、不安定さを監視し、テスト基盤も改善する |
| 6. 自動化検討はプロジェクト初期から | 操作性、合否判定、テストデータ投入のしやすさを、システム設計の段階から検討する |
| 7. 自動テストで新種のバグが見つかることは稀である | 新しい種類の問題探索と、既存機能の回帰検知を、同じ期待で扱わない |
| 8. テスト結果分析という新たなタスクが生まれる | 製品の不具合、テストコード、実行環境を切り分けられるログと担当を用意する |
8原則に加えて確認したい6つの運用項目
ここからは、上の8原則そのものではなく、CI/CDで自動テストを継続するために、筆者が追加で確認したい運用項目です。
- 繰り返しが多く、結果を機械判定でき、失敗時の影響が大きいテストから自動化する
- テスト同士をできるだけ独立させ、実行順に依存させない
- テストコードも本番コードと同じようにレビューし、保守する
- 失敗時に、どこで何が起きたか短時間で分かるログや成果物を残す
- 不安定なテストを放置せず、原因の修正、隔離、削除を判断する
- 失敗や運用で得た情報を、新しいテスト観点や設計改善へ戻す
自動化の目的は、単に人件費を減らすことではありません。変更へのフィードバックを早くし、同じ確認を再現可能にし、人が探索や判断に使える時間を増やすことです。
ソフトウェアテストの7原則
ISTQBのFoundation Level Syllabusでは、ソフトウェアテストの考え方を7つの原則で整理しています。
以下の左列は、JSTQB Foundation Levelシラバス Version 4.0(日本語版、1.3節、PDF 18ページ)の原則名です。右列は、各原則を読者が現場で使い分けやすいように、筆者が追加した実務上の補足です。
| JSTQB日本語シラバスの原則名(原文) | 筆者の実務上の補足 |
|---|---|
| 1. テストは欠陥があることは示せるが、欠陥がないことは示せない | テストが通った事実だけで、欠陥がないと断定しない |
| 2. 全数テストは不可能 | 入力、状態、経路、組合せのリスクを比較し、テストの優先順位を決める |
| 3. 早期テストで時間とコストを節約 | 実装後だけでなく、要件と設計の段階でもレビューとテスト分析を始める |
| 4. 欠陥の偏在 | 過去に欠陥が集中した機能、変更量が大きい箇所、影響の大きい経路へ重点配分する |
| 5. テストの弱化 | 同じテストだけを繰り返さず、データ、観点、組合せを見直す |
| 6. テストはコンテキスト次第 | システムの利用目的、事業リスク、法規制、運用条件に合わせてテストを変える |
| 7. 「欠陥ゼロ」の落とし穴 | 仕様どおりでも利用者のニーズや事業目標を満たさない場合があるため、妥当性も確認する |
最後の原則は、absence-of-errors fallacyと呼ばれます。テストがすべて成功しても、作るべきものを間違えていたら品質の高いシステムとはいえません。
よくある混同を最後に整理する
| よくある理解 | 正しい整理 |
|---|---|
| テストレベルは必ず4つ | ISTQB CTFL v4.0.1では5つ。現場の4区分では、2種類の統合テストを「結合テスト」としてまとめる場合がある |
| 回帰テストはシステムテストの後に行うテストレベル | 変更の影響を確認する目的であり、どのレベルでも行える |
| 修正確認テストと回帰テストは同じ | 前者は元の欠陥が直ったこと、後者は変更による既存機能への悪影響がないことを確認する |
| E2Eテストとシステムテストは同じ | 重なることはあるが、前者は一連の経路、後者は統合済みシステムと要件に注目する |
| 統合テストはAPIやDBをすべてモックにする | モックだけでは実接続の差異を確認できないため、目的に応じて実物に近い環境も使う |
| カバレッジ100%なら十分 | 実行した範囲の指標であり、要件漏れや期待結果の誤りは保証しない |
| UIテストを増やすほど安心 | 実行時間と保守コストが増えるため、単体・API・結合テストとの配分を考える |
| 自動化すれば手動テストはいらない | 探索、使いやすさ、未知の問題を見つける作業には人の判断が必要 |
| CIはテストの種類 | CIは変更を統合し、ビルドやテストを継続的に回す仕組み |
実務で使えるテスト計画チェックリスト
- 要件ごとに、どのテストレベルで確認するか決めた
- 要件、設計、コードをレビュー・静的解析で確認する範囲を決めた
- 正常系だけでなく、異常系と境界値を入れた
- 重要な組合せと過去障害の再発防止ケースを入れた
- コンポーネント統合とシステム統合の対象を分けた
- コンポーネント、統合、E2Eの役割が重複しすぎていない
- モックで確認できることと、実物でしか確認できないことを分けた
- 機能だけでなく、性能、信頼性、互換性、セキュリティ、使いやすさを検討した
- スモークテストで、詳細テストへ進める状態か確認できる
- 欠陥修正後の修正確認テストと、影響範囲に応じた回帰テストを分けた
- 探索的テストやモンキーテストの目的、対象、記録方法を決めた
- CIの失敗から原因を調べられるログと成果物が残る
- テストに失敗した変更が、デプロイへ進まない設定になっている
- 不安定なテストの担当と修正期限を決めた
- リリース後に見つかった欠陥を、テストと設計へ戻す流れがある
参考・確認先
- ISTQB Certified Tester Foundation Level Syllabus v4.0.1
- Android Developers UI/Application Exerciser Monkey
- Microsoft Learn ASP.NET Core load/stress testing
- W3C Web Accessibility Initiative Evaluating Web Accessibility
- Selenium公式 Page object models
- Playwright公式 Page object models
- pytest公式 How to parametrize fixtures and test functions
- GitHub Docs Building and testing Python
- OWASP Web Security Testing Guide
- The Practical Test Pyramid
- テスト自動化研究会: テスト自動化の8原則
関連記事
- ウォークスルーレビューとは 作成者が説明して認識ズレを減らす進め方
- レビュー指摘を成長につなげる受け止め方と修正の進め方(今後公開予定)
まとめ
- V字モデルは、開発成果物とテストの対応を考えるために使う
- 静的テストと動的テストを組み合わせ、早い工程から問題を見つける
- ISTQBの5つのテストレベルと、現場で使われる4区分の違いを理解する
- テストレベル、テスト技法、テストタイプ、変更に伴うテスト、実行方法を分けて整理する
- 同値分割と境界値分析で、少ないケースから重要な入力を選ぶ
- コンポーネントテストを土台にし、統合テストと少数のE2Eテストを組み合わせる
- 修正確認テストで欠陥の修正を確認し、回帰テストで変更の悪影響を確認する
- モンキーテストや探索的テストなどは、目的、対象、方法、合格条件を確認して使い分ける
- テスト自動化研究会の8原則と、追加の運用項目を分けて理解する
- カバレッジや自動テストの成功だけで品質を断定しない
- CI/CDでは、速いテストから段階的に実行し、成功した変更だけをデプロイへ進める
- 手動テストと自動テストを対立させず、得意な確認を分担する
おわりに
ソフトウェアテストは、実装後に不具合を探すだけの工程ではありません。要件と設計の段階から「何をどう確かめるか」を決めることで、手戻りを減らし、変更しやすいシステムを作れます。
Wealthy Designでは、こうしたWebシステム開発や品質改善に取り組むエンジニアを募集しています。会社の取り組みは、会社サイトにまとめています。