【第4回】『具体と抽象』から見る、テスト設計
<【連載】具体と抽象を往復しよう! 記事一覧>※クリックで開きます

はじめに

前回の記事では、具体と抽象の往復が、デザインや直感にどのように表れるのかを書きました。

デザインでは、ユーザーの頭の中にある「こうしたい」という抽象的な期待を、ボタンやアイコン、色、配置といった具体的なUIへと変換します。直感では、過去の具体的な経験から抽象化されたパターンが、思考を高速化します。

つまり、抽象は単に物事を整理するためだけにあるのではありません。具体的な成果物をつくるためにも、複雑な状況を素早く判断するためにも使われています。

今回は、これまでの話をQAとソフトウェアテストの領域に戻します。

テストは、目の前にあるソフトウェアという具体を観察し、そこからリスクやテスト条件、テスト観点といった抽象をつくり、その抽象を再びテストケースや実行手順という具体へ落とし込む活動です。

つまり、テスト設計は、具体と抽象の往復そのものです。

前回の記事の最後では、直感による思考のショートカットは便利である一方、見えている関係だけを信じてしまう危うさもあると書きました。人はパターンを見抜けるからこそ、早合点もします。

そこでQAエンジニアが行うテスト活動では、直感に頼るだけではなく、関係性そのものを構造として捉え直す必要があります。さらに、さまざまな抽象度で複雑に発散したテスト観点を人間が扱えるように、適切な抽象度で階層化する必要もあります。

今回の記事では、次の順番で話を進めます。

まず、仕様や要件を条件と結果の関係として捉え直す方法を見ます。次に、テストがなぜ必要なのか、テストをどのようにリスクとして捉えるのかを整理します。そのうえで、テスト要求分析、テストアーキテクチャ設計、テスト詳細設計、テスト実装というテスト開発プロセスを、具体と抽象の往復として見ていきます。

テストケースをたくさん作ることが、テスト設計ではありません。

テスト対象を理解し、重要なものを抽象化し、構造化し、必要十分な具体へ戻すこと。これが、今回考えたいテスト設計の本質です。

抽象は関係性を見抜く:逆・裏・対偶という見方

前回の記事では、抽象化されたパターンが直感を生み、思考を高速化するという話を書きました。

しかし、直感は便利である一方、見えている関係だけをそのまま信じてしまう危うさもあります。「この条件なら、きっとこうなるだろう」と思い込んでしまうからです。

そこでテスト対象を理解する上では、関係性そのものを形式として捉え直す視点が重要になります。その一つが、命題を「逆・裏・対偶」で捉える考え方です。

前回の記事で扱ったように、抽象化は単に「似ているものをまとめる」だけではありません。複数の事象に共通する関係性を取り出し、形式として扱うことも抽象化です。

仕様や要件の多くは、「もしこうなら、こうなるはずだ」という形で記述できます。これは論理の世界では、「PならばQである」という命題です。

  • 元の命題:P ならば Q
  • P:条件、操作、入力
  • Q:結果、状態、出力
  • 逆:Q ならば P
  • 裏:Pでない ならば Qでない
  • 対偶:Qでない ならば Pでない

こうして書くと、少し数学のように見えるかもしれません。しかし、実際にはかなり実務的な考え方です。

ログイン機能に当てはめる

たとえば、ログイン機能に当てはめると、次のように整理できます。

論理 テスト観点 テスト例(ログイン機能)
元の命題(P → Q) 正常系テスト 有効なIDとパスワードでログインでき、マイページに遷移するか。
裏(Pでない → Qでない) 準正常系・異常系テスト IDまたはパスワードが間違っている場合に、ログインできないか。
逆(Q → P) 状態の正当性・セキュリティ ログイン状態になっているなら、正当な認証経路を通ったはずだと考え、URL直打ちやセッションの不正利用ができないか。
対偶(Qでない → Pでない) 原因の切り分け ログインできない場合、本当にIDやパスワードが無効なのか。それともサーバー障害など別の原因なのかを区別できるか。

ここで大事なのは、元の命題だけを見ていると、テスト観点がかなり限定されてしまうということです。

「有効なIDとパスワードならログインできる」という仕様だけを見ていると、正常系の確認で満足してしまいがちです。しかし、逆や裏や対偶まで視野を広げると、セッションの正当性、URL直打ち、ブラウザバック、エラーメッセージの妥当性、原因の切り分けなど、別の角度から仕様を見られるようになります。

つまり、ここで行っているのは、「ログイン」という機能を、単なる具体的な画面操作ではなく、「条件と結果の関係」という抽象モデルで捉え直すことです。

前回の記事で言えば、見た目の違いを超えて共通する構造を抜き出しているのと同じことです。

抽象モデルの便利さと限界

ただし、ここで注意が必要です。

ログイン失敗の原因は、IDやパスワードの妥当性だけとは限りません。サーバー障害、ネットワーク障害、外部認証基盤の問題など、別の要因もあります。

「サーバー起因か、ユーザー起因かを区別できるか」というテストは、先ほどの命題の枠組みの外側にある観点です。対偶の確認だけで、すべての原因を説明できるわけではありません。

このあたりに、抽象モデルの便利さと限界が両方表れています。

モデルは思考を整理してくれます。しかし、現実を完全には覆い尽くせません。前回の記事で引用したGeorge Boxの言葉、「すべてのモデルは間違っている、しかし有用である」が、ここでもそのまま当てはまります。

共通点と相違点を適切にどう掴むのか。どこまでを同じ構造として扱い、どこからを別物として扱うのか。

この判断が、抽象的に考えるコツなのだと思います。

テストは具体と期待を突き合わせる活動である

ここまで、仕様や要件を関係性として抽象化する話をしました。では、そもそもなぜテストが必要なのでしょうか。

テストとは、目の前にある具体的なソフトウェアと、そこから期待される振る舞いを突き合わせる活動です。

たとえば、会議室予約システムであれば、利用者が実際に会議室を予約します。その結果、予約が登録され、予約完了が表示され、必要な情報が関係者へ伝わるかもしれません。これが、実際に起きたこと、つまり具体です。

一方で、テストをする前には、「この条件なら、この結果になるはずだ」という期待があります。

  • 空いている会議室なら予約できる
  • 予約済みの時間帯なら予約できない
  • キャンセルした会議室は再び予約できる
  • 権限のない利用者は他人の予約を変更できない

これらは、現実の利用目的や仕様から取り出した、期待される振る舞いです。

具体的なソフトウェア
        ↓
期待される振る舞い
        ↓
一致しているかを確認する

つまり、テストは単に画面を操作することではありません。実際に起きたことと、起きるはずだったことを比較することです。

テストはリスクを具体化する活動でもある

テストのリソースは有限です。すべての入力値、組み合わせ、環境、ユーザー行動を確認することはできません。

そこで、「何を確認するか」を決める前に、「何が起きると困るのか」を考えます。

会議室予約システムであれば、同じ時間帯に二人が同じ会議室を予約できてしまうと、重要な会議を開催できなくなるかもしれません。

予約処理の不備
   ↓
重複予約が登録される
   ↓
会議室を利用できない
   ↓
業務に支障が出る

この具体的な失敗の経路から、「予約の整合性」や「重複の防止」といった抽象的なテスト条件を取り出します。そして、その重要度に応じて、どこを厚く確認するのかを決めます。

テスト設計では、具体的な機能や利用場面からリスクを抽象化し、その抽象的なリスクを、具体的なテストへ戻していくのです。

テストを設計するまでのプロセスは、抽象度を変換する活動である

テスト要求分析、テストアーキテクチャ設計、テスト詳細設計、テスト実装という流れは、単に活動を区切るためのものではありません。

それぞれ、異なる抽象度の問いを扱っています。

テスト要求分析:具体から抽象へ

まず、実際の利用場面やシステムの構造を見ます。

利用者は何をしたいのか。どの失敗が困るのか。システムのどこが複雑なのか。

こうした具体的な事実から、「何を守るべきか」「何をテストすべきか」という抽象的なテスト条件やリスクを取り出します。

続きを読むにはログインが必要です。
ご利用は無料ですので、ぜひご登録ください。

SHARE

  • facebook
  • twitter

SQRIPTER

北村 駿(きたむら しゅん)

記事一覧

元バンドマン・元バーテンダーのQAエンジニア。現在はとあるQA組織の内製化とQAテックリードを担いながら、ピープル・ワーク両面でマネジメントも奮闘中。

Xアカウント: https://x.com/max_qae
Zenn: https://zenn.dev/max_qae

Sqriptsはシステム開発における品質(Quality)を中心に、エンジニアが”理解しやすい”Scriptに変換して情報発信するメディアです

  • 新規登録/ログイン
  • 株式会社AGEST