Pythonスキルの習得

ソフトウェアテスト技法 入門

アイキャッチ

初めに

プログラム業務に携わる方で

  • デバッグに費やす時間が半端ない
  • リリース後にバグを発生、相手先に迷惑をかけている。(最悪は、賠償請求・・)
  • いつもクレーム対応に追われている

という状況に見舞われていないでしょうか?

本記事を読むと、品質担保の考え方の一つ、「ソフトウェアテスト技法」を網羅して習得できます。

またPythonでコードを記述している箇所もありますが、簡単なコードのみです。Pythonを知らない方でも十分に理解できる内容になっています。

書籍『ソフトウェアテスト技法ドリル』、『はじめて学ぶソフトウェアテスト技法』を参考にしています。

また本記事は、ブラックボックステストのみを対象にします。これは、テスト対象物の内部構造、実装に関する知識を必要としないテストです。(その反対として、ホワイトボックステストがあります。)

ブラックボックステストは、単体、結合、システム、受け入れテストと、全てのテストに適用できます。

ソフトウェアを実施する上でのスタンス

全てをテストするのは、無理であるという前提に立ちます。下記のような単純な掛け算でさえ、あらゆる数字をテストするのは不可能です。

def multiple(a, b):     
    return a * b

2つの引数に、整数、マイナス、少数・・・と考えられるだけでも、無限の組み合わせが代入でき、全てをテストするのは不可能です。

よって「管理できる少ないテスト数で、多くのバグを発見する」というスタンスで臨むのが、テスト技法です。

次からは、具体的なテスト技法をご紹介致します。

ソフトウェアテスト技法の種類

同値クラステスト

この方法は、十分なカバレッジ(網羅性)を担保しつつ、テスト数を減らす事ができる方法です。

同値クラスというのは、「テスト上では、同じ処理になる範囲」の事です。
これだけではよく分からないと思うので、具体例を見ていきます。

if x < 3:
    Aの処理を実施
elif x <= 10:
    Bの処理を実施
else:
    Cの処理を実施

上記コードの場合、変数xが1の場合と2の場合は、どちらも「Aの処理を実施」になります。

よって、xを1にするか、2にするかは、テストとしては同じ処理であり、こういうのを同値クラスと呼ばれています。

同値クラステストの場合、クラスの数だけテストします。上記例の場合だと、「A、B、Cの処理」分の3つを検証します。

実際はブラックボックステストなので、内部コードが分からない状態でのテストを前提とします。最初に決めた要件と仕様書に基づいて、テストをします。

つまり同値クラスを定義した仕様書がなければ、テストできません。

境界値テスト

同値クラスの境界とその前後をテストする方法です。これは境界には、たくさんの欠陥が潜んでいる事が分かっているからです。

もう一度、同じコードを事例に具体例を紹介していきます。

if x < 3:
    Aの処理を実施
elif x <= 10:
    Bの処理を実施
else:
    Cの処理を実施

上記コードの場合、3つ同値クラスがあり、境界は、変数x=310の2つがあります。

よってこの場合、境界の前後も含めて、xは、2, 3, 4, 9, 10, 11の6つをテストするのが、完璧な境界値テストになります。

ドメイン分析テスト

同値クラステスト、境界値テストは、検証する変数が1つのみでしたが、複数の変数を一緒にテストするための方法です。

複数の変数から成る条件があると、変数間で相互作用を起こす場合があります。変数を1つ1つ検証していっても、バグが発見できない可能性があります。

上記の説明では、何を言っているか分からないと思いますので、具体例で見てみます。

大学の入学試験で、「数学の点数」と「英語の点数」の2教科(変数)しかない場合を考えてみて下さい。

ここでの合格条件は以下の2条件を満足する必要があるとします。

条件因子合格条件
数学 70点以上
数学 + 英語 120点以上

ここには、先に述べた2つが存在します。
・複数の変数(ここでは、数学、英語の2つ)
・変数の相互作用で表現できる条件がある。(数学+英語 のように数式で表現できる条件がある。)

また上記合格条件は、論理式で表現できます。(数学80点以上 AND 数学+英語120点以上 のように、AND、ORで表現するものが論理式になります。)

後に出てくる「デシジョンテーブルテスト」との違いは、変数の相互作用で表現できる条件が有るか無いかです。(有る場合、こちらの方法を採用します。)

この場合、テストケースは下表の4つになります。下表「テストケース」のそれぞれのが、1回のテストに相当します。(テスト設定値は参考例)

上表の「90+30」等の表現は、「数学+英語」を意味しています。

重要なのは、検証箇所を一ヶ所にする点です。検証箇所を複数箇所にした場合、エラー発生時、どこで発生したか分からなくなります。(また、1つのエラーは、他のエラーを隠すため、それを防ぐ意味もあります。)

そのために、着目する条件をon、offポイントと変化させて検証し、着目しない条件はinポイントに設定します。

この、「on/off/in」ポイントの概念は次の通りです。

・ onポイント: 境界値上の値 X > 20なら、20が境界値
・ offポイント: onに隣接する値 onが条件を満たしている場合(ドメイン内と呼ばれる)は、ドメイン外の隣接値を使用。逆も然り。具体例↓

・ inポイント: on/offポイント以外の値でドメイン内の値(条件を満たしている値)

デシジョンテーブルテスト

各条件が独立していて、論理式で表現できる場合に使用できます。具体例を見ていきます。

上表の場合、(国語の80点以上)AND(数学の80点以上)AND(物理80点以上)なら、授業料免除になります。

デシジョンテーブルの問題点

上図の場合、2値条件(YES/NO)が3条件あるので、23 = 8通りでだけですが、10条件あると、210 = 1024通りと恐ろしいテストケース数になってしまいます。

それを解決するのが、次のペア構成テストです。

ペア構成テスト

全ケースのテストは諦めるが、バグを効率よく発見するというスタンスに立った方法です。

ペア構成テストというのは、条件の全てのペアをテストする物になります。

全てのペアをテストするというのは、デシジョンテーブルの例で言うと、「国語と数学」、「数学と物理」、「物理と数学」という3通りのペアに対し、0:(80点未満)、1:(80点以上)とすると、「0、0」、「0、1」「1、0」「1、1」の4通りのテストをするという意味です。

バグのほとんどは、単体モジュールでの発生、もしくは1つずつのモジュールの組合せで発生すると思われているため、本方法が有効だと考えられています。

実際はなぜ有効なのかは、分かってません。しかし、欠陥のほとんどをこの方法で検出できるとの報告結果があります。(76%とか、98%とかの報告例があります。)

この方法を使用した場合、先の例(上述のデジジョンテーブルテストの例)では3通りのペアに対して、4通りの値をテストする必要があり、合計3✖️4=12通りになります。

そうなると、デシジョンテーブルテストに比べ、テスト数が全然減っていません。それを解決するのが、直行表を使ったテストになります。

直行表

自然科学の分野で、実験計画法で使われている「直行表」をプログラミングに適用した物になります。直行表を使えば、少ないテストで、全てのペアの組合せを検証できます。

例として、先ほどの条件(2値条件(80点以上、未満)が3つ(国語、数学、物理のペア)ある場合)の直行表を下記に示します。

各値は「0:80点未満」、「1:80点以上」を意味しており、各が1つのテストになっています。

この4つのテストだけで、全てのペア、全ての組合せがテストができています。例えば、国語と数学だけを抜き出すと、「0、0」、「0、1」「1、0」「1、1」の4通りテストができており、他のペアでも同じ事が分かります。

この直行表は、L4(2^3)と表現されます。 実験数は4つ(L4)で、2値条件が3つ(2^3)という意味です。

よって、本検証をする場合、直行表を見つけてくる必要があります。

タグチ計画のカタログのサイトが参考になります。

またこの直行表を使用した方法とは別に、全ペアを生成できるアルゴリズムもあります。詳しくは、本「ソフトウェアテスト技法」を参考にして下さい。

状態遷移テスト

今までのテストは、条件だけで振る舞いが決まるソフトウェアに有効でしたが、このテストは、現在の状態とその遷移によって振る舞いが変わるソフトウェアに有効です。

状態遷移テストは、目的に応じて2種類のテストがあります。

状態遷移図を使ったテスト

簡単に全体を確認するためのテストになります。具体的な事例を見てみます。

下記図はプリンタを事例に、一部の機能のみを表現したものになります。

「電源をボタンON」イベントが発生すると、「プリンタ起動中」の状態になり、そこに「印刷開始」イベントが発生すると、「印刷中」状態になります。

この図に従えば、遷移は全部で4つなので、下記のテストが全てだと考えてしまいます。

  • 「初期状態」で電源ボタンを押して、「プリンタ起動中」への遷移確認
  • 「プリンタ起動中」で印刷開始イベントをおこし、「印刷中」への遷移確認
  • 「印刷中」で印刷終了イベントをおこし、「プリンタ起動中」への遷移確認
  • 「プリンタ起動中」に電源ボタンOFFをして、「初期状態」への遷移確認

実はこの方法だけでは、抜け漏れが発生します。それを防ぐのが次に紹介する状態遷移を使ったテストになります。

状態遷移表を使ったテスト

先のプリンタを事例にした、状態遷移表を見てみます。

列に状態、行にイベントを記述し、各値は、遷移状態先を示しています。(N/Aは Not Applicableの略で、ここでは決めていないという意味になります。)

こうして見ると、状態遷移図では抽出できなかった、N/Aの部分が抽出できています。

また赤字のN/Aに気づけたのは、個人的に重要だと思います。「印刷中に別の印刷シグナルが来たら、どうするのか?」は、製品の重要な仕様にも繋がる可能性があり、この手法を用いれば、重大な仕様漏れに気づく事ができます。

このN/Aに、どの状態に遷移するかを決めます。(もしくは、どこにも遷移しないと決めます。)

テストの仕方は、各状態で各イベントを入力し、目標の遷移先になっているのかを確認していきます。

しかし全ての状態、全てのイベントを確認しても、テストとしては弱いとされています。

「状態A」→「状態B」の確認をして、 それとは別に「状態B」→「状態C」が確認できても、「状態A」→「状態B」→「状態C」になるとは限りません。

詳しく知りたい方は、「Nスイッチカバレッジ」という用語を調べて頂ければと思います。

ユースケーステスト

ここまでのテストは、システムの一部のみが対象でしたが、システム一連の流れを最初から最後まで通したテストがこちらです。

ユースケースシナリオ等を使用して検証致します。

具体例を見てみます。下図は、ユースケース事例です。(一部のみを抜粋。またシナリオも、分かりやすさ重視で簡単にしています。)

上表に則り、「主成功シナリオ」に対して、1つ以上のテストケース、拡張シナリオ、それぞれも1つ以上のテストケースを作成致します。

最後に

本記事では、ブラックボックステストを題材に、7つテスト技法を紹介致しました。冒頭でお話した通りですが、テスト技法というのは、「考えられる全てのテストは数が多すぎて無理な場合、管理できるテスト数で、効率良くバグを発見する」方法です。

しかし、発生してしまうと致命傷になる機能に関しては、このテスト技法とは別で、重点的にその部分を検証する必要があります(ピンポイントテストと呼ばれています)。

またブラックボックステスト検証では、検証されないコードが残ってしまう可能性があります。しかし効率的にバグを発見できる優れた方法であるのも事実です。そこを理解して、使用して頂ければと思います。

更に詳細を知りたい方は、本記事でも参考にした、下記本がお薦めです。

本記事の全てを網羅しており、具体例も豊富で、お薦の一品です。

本記事が少しでもお役に立てれば、嬉しい限りです。