設計向けとテスト設計向けの適切な仕様表現の差異(デシジョンテーブルを例として)

設計向けとテスト設計向けでは、適切な仕様表現について認識に差異が出ることがあります。

題材として、以下の仕様をデシジョンテーブルで表現する場合を考えます:

題材とする仕様

  • 組み込み機器の単軸制御モード機能が対象

  • この機能は次の3つの入力を持つ
    • 省電力化モード(とり得る値:ON、OFF)
    • 制御方針(とり得る値:精密重視、速度重視)
    • 目標との距離(とり得る値:整数値[cm])

  • この機能は次の出力を持つ
    • 速度モード(とり得る値:高速モード、中速モード、低速モード)

  • この機能は出力の速度モードを次のように決定する
    • 省電力化モードがONの場合、低速モードで固定する
    • 省電力化モードがOFFの場合、以下に従う
      • 目標との距離が10cm未満の場合、低速モードを選択する
      • 目標との距離が10cm以上かつ、制御方針が精密重視なら、中速モードを選択する
      • 目標との距離が10cm以上かつ、制御方針が速度重視なら、高速モードを選択する

 

設計向けのデシジョンテーブルの例

設計では、実装の方針がわかる前提下ならば、デシジョンテーブルを簡単化しても支障はありません。むしろ必要十分な範囲内で情報を簡単化した方が、都合が良い場合が多いです。

今回の仕様では、以下のようにデシジョンテーブルを表記できます。

f:id:goyoki:20200628225659p:plain

 

テスト設計向けのデシジョンテーブルの例

一方、テスト設計向けに、デシジョンテーブル法に基づいてテーブルを作る場合、上記のようにデシジョンテーブルを簡単化できるとは限りません。どこまで簡単化できるかが、処理順序や品質リスクに依存するためです。

まず以下のような実装が行われている場合について考えます。

# 速度モード設定処理()にはモードに応じた障害のリスクがあるとする

def 単軸制御モード機能(省電力化, 制御方針, 目標との距離):
    if 省電力化 == ON:
        速度モード設定処理(低速モード) #1
        return

    if 目標との距離 < 10:
        速度モード設定処理(低速モード) #2
        return
    
    if 制御方針 == 精密重視:
        速度モード設定処理(中速モード) #3
        return
    else:
        速度モード設定処理(高速モード) #4
        return

この場合、シンプルな分岐構造で仕様が実装されているため、前述の簡単化デシジョンテーブルを使っても問題ありません。テスト技法に則り、デシジョンテーブルの各列をテストケースに展開すれば、すべての速度モード設定処理()を網羅するテストケースを用意できます。

一方で、次のような実装が行われている場合について考えます。

# 速度モード設定処理()にはモードに応じた障害のリスクがあるとする

def 単軸制御モード機能2(省電力化, 制御方針, 目標との距離):
    if 制御方針 == 精密重視:
        if 省電力化 == ON:
            速度モード設定処理(低速モード) #1
        elif 目標との距離 < 10:
            速度モード設定処理(低速モード) #2
        else:
            速度モード設定処理(中速モード) #3
        return
    else:
        if 省電力化 == ON:
            速度モード設定処理(低速モード) #4
        elif 目標との距離 < 10:
            速度モード設定処理(低速モード) #5
        else:
            速度モード設定処理(高速モード) #6
        return

この実装の場合、前述の簡単化したデシジョンテーブルに従ってテストケースを導出すると、一部の速度モード設定処理を網羅できず品質リスクが残ります。

この実装に基づいて適切にデシジョンテーブルを簡単化するならば、一例として以下のようなものになるでしょう。

f:id:goyoki:20200628225724p:plain

また機能の処理が複雑なコードで分散実装されていたり、見えにくい品質リスクが散在していたりする場合だと、実装から順序性や品質リスクが読み取れなくなる場合があります。そうなると、デシジョンテーブルは全く簡単化できない場面もあり得ます。

すなわち、設計と同じように簡単化できない場合があるということです。

なおこの話の参考文献として、 ソフトウェアテスト技法練習帳 に解説があり、お勧めできます。

 

設計向けとテスト設計向けの適切な仕様表現の差異

テストの導出元にするデシジョンテーブルをどこまで簡単化できるかは、順序性、広く言えば品質リスクに依存します。そしてテスト設計ではより包括的に品質リスクに対応する必要があることから、設計のための仕様より、簡単化できない場面が多いです。言い換えると、テスト設計では、設計と比べ、より広い視点で、情報が補強された仕様表現が求められる場面が多いです。

なお「より広い視点で、情報が補強された仕様表現が求められる」といっても、現実でそれを十分に実現できる場面は多くありません。テスト用に仕様を作り直すコストはないのが普通ですし、そもそも品質リスクは広く・見えにくく潜在していて、仕様化ですべて対応できないためです。その現実に立ち向かうため、以下のような活動が重要になってくると感じます。

  • 設計や実装でのリスクコントロールの工夫。少ないテストでも大丈夫なように作る。
  • 探索的テストによる補完。仕様の情報不足を、テストエンジニアの能力や学習結果で補完する。
  • グレーボックステストの拡充。設計やコードの構造に基づいてテスト設計の穴を補強する。
  • 無則のテストの導入。ペアワイズ法などで仕様化されていない条件もテストする。
  • 品質保証の重ね合わせ。コードレビュー、ユニットテストシステムテスト、専任チームによる品質保証などを組み合わせて、品質リスクの見落としを減らす。