0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今までの経験から考えるテストケースの作り方・作られ方

Last updated at Posted at 2025-08-06

はじめに

色々な開発チームを渡り歩いて、テストほど組織ごとに考え方が異なるものはなく、特にスタートアップ企業においてはどのようにテストにテストケースを設定するか悩ましいものだと考えています。
この記事では、私が実際に受託して自ら編み出した方法や、色々な開発チームで見てきたエッセンス、OSSのコードなどを総合的に鑑みてテストケース設定をどのように考えるべきか、感じていることを書いています。

要するに、主観的な記事です。

条件の網羅

テストケースはあり得る条件に対して網羅的でなければなりません。しかし例えば関数が以下のような形式であり

function f(arg1, arg2, arg3) => result

かつ、状態変数state1, state2によって結果が変わるとします。これを便宜上f(arg1, arg2, arg3, state1, state2)と表現するとします。また、arg1のバリエーション数をV(arg1)のように表記します。

この時、何も考えずに網羅性のあるケースを作るのは、それぞれの値が取り得るパターンの積を取ればよいように見え、そうするとパターン数としてはV(arg1)V(arg2)V(arg3)V(state1)V(state2)で相当なケース数に膨れ上がることが予想されますね。どうしたものか…。

独立・従属

例えばarg1, arg2は組み合わせによって異なる効果を発揮するようなケースもありますが、arg2による挙動の変化はarg1の値に影響されないこともあります。ありますというか、どちらかというとそのようなケースの方が多いでしょう。

組み合わせによって効果を発揮する変数は従属であると言え、そうでなければ独立であると言えます。

arg1, arg2が互いに従属である場合は以下のような書き方になります。V(arg1) = V(arg2) = 3ならば、ケース数はV(arg1)V(arg2) = 9です。

case "arg1 is xxx"
    case "arg2 is xxx"
    case "arg2 is yyy"
    case "arg2 is zzz"
  
case "arg1 is yyy"
    case "arg2 is xxx"
    case "arg2 is yyy"
    case "arg2 is zzz"

case "arg1 is zzz"
    case "arg2 is xxx"
    case "arg2 is yyy"
    case "arg2 is zzz"
  

一方、独立なら以下のようになります。V(arg1) = V(arg2) = 3ならば、ケース数はV(arg1) + V(arg2) = 6です。

case "arg1 is xxx"
case "arg1 is yyy"
case "arg1 is zzz"

case "arg2 is xxx"
case "arg2 is yyy"
case "arg2 is zzz"

論理的に網羅性は変わりませんが、ケース数を抑えることができます。
それと、独立か従属か、テストケースを見ただけでモジュールの仕様が判断できるのもいいですね。

ハッピーパスと変数変更

先の例では引数と条件が分かりやすい変数で表現できていて、網羅するのが比較的簡単でした。が、複雑なモジュールのブラックボックステストを行う場合、話は難しくなってきます。

そこで、テストケースの捉え方を変え、以下のようなケースが存在すると考えます。

  • ハッピーパス: 想定される一般的な正常系の条件で実行した場合
  • オルタナティブパス: ハッピーパスと異なるが、用意された代替的な想定条件で実行した場合
  • エッジケース: 普通に使う分には起こり得ないが、オルタナティブパスの延長線上にある条件で実行した場合
  • 準異常ケース: ユーザーの入力エラー等、想定される範囲で処理を中断すべきケース
  • 異常ケース: 通常は起こり得ないが、システムとして何かの問題が生じたときに起こり得るもので処理を中断すべきケース

捉え方は変えていますが、網羅性を考えるという事の延長線上の話であって、その中でいかに見落としを防ぐか、というものには違いありません。
勘のいい方は気が付いたかと思いますが、単純に変数を動かしてチェックする流れでは存在したが、この考え方では登場しなくなったテストケースがある可能性もあります。しかし、変数を1つ1つ動かして考えるのは人間の認知にはあまり向いておらず、こちらの考え方の方がむしろ有利に働くことが多いと見ています。

独立・従属の観点はハッピーパスと変数変更のプラクティスにおいても存在しますが、割と自然に独立な変数をむやみに組み合わせたりはしなくなるように感じます。

TDD

TDD(テスト駆動開発)とは、テストを書く事によってモジュールの望ましい挙動を定義し、その定義に従ってコードを実装するという開発スタイルです。
詳しい型が多い分野だと思うので下手に色々書くのも嫌ですが、とりあえず、ただ先にテストコードを書くのがTDDなのかというと、そうではないです。

Red-Green-Refactorパターン

TDDの中にも色々流派があるようですが、著名な提唱者のKent Beck氏が示したプラクティスとして、よく知られているものがRed-Green-Refactorパターンです。以下、Red-Green-Refactorに従って考えるものとして、話を続けますが、まずはRed-Green-Refactorとはどういうものか簡単に示します。

RED

まずは仕様変更に従ってテストコードを追加・変更します。プロダクションコードに実装がないか、古い実装であるためこの時点でテストは必ず失敗します。

GREEN

テストコードの変更に従って、プロダクションコードに変更を加えます。ここでテストが成功すればプロダクションコードは仕様を満たすことが保証されています。

Refactor

全てのテストが成功する状態を保ちつつ、モジュールのコードをベターな形に変更します。テストは成功した状態なので、プロダクションコードは引き続き仕様を満たすことが保証されています。

TDDによるテストケースの生成

「条件の網羅」の章では、テストをプロダクションコードの開発プロセスと分離した状態で物事を考えていました。もちろんTDDに従わない場合はそれでも構いませんから、比較的色々な考え方でテストケースを構成することができます。
しかし、TDDを実践する場合「変数のパターンが~~であるからプロダクションコードがこうで…」とはなりませんから、自然とハッピーパスと変数変更がフィットするようになります。

まとめ

タイトルにもある通り、どちらかというと「作られ方」だと捉えていますが、プラクティスとしての結論はハッピーパスと変数変更の考え方によってケースを整備することです。

結論だけ見ると「なぜだろうか?」「もっと他に良い方法があるのではないか?」と思うかもしれませんが、

  • 人間が条件の網羅性を評価する
  • TDDのプロセスにフィットする

という2つの理由から、この作り方が合理的なのです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?