●プログラムのテスト
テスト内容(仕様)は、作成物の仕様が決った直後に行います。
テストプログラムは、作成物のプログラムよりも先に作成するとよいでしょう。
テストとは、デバッグするためではなく、正常を証明するために行います。
- 『仕様作成』
- 試験関数、前提関数、条件一覧の明示
- 実現可能なテストケースの明示
- 手動テスト(人間によるチェック項目)の明示
- クイックテスト(機械によるチェック項目)の明示
- 『手動テスト作成』:特定の条件について
- 入力データの作成(〜をするプログラムの作成)
- 人間による「データ」チェックのための出力データ変換の作成
人間によるチェックポイントではブレークをかける
- 手動テストの実施
- 出力データの記録(〜をするプログラムの作成)、
仕様変更をドキュメントに反映
- 手動テストは、リリース版のみ行います。
(リリース版がマスターなので)
- バグが残っている場合は、状況を記録し、
自動テストをスキップするように #if で分ける
#if !defined(FOR_QUICK_TEST)
- 『自動テスト作成』:すべての条件について
- (手動テストが合格してから行う)
- 比較プログラムの作成
クイックテストでは手動テストを実施しない #ifdef で分ける
- 出力データをクイックテストの比較用に変換する
プログラムの作成
- クイックテストの実施
- クイックテストは、リリース版とデバッグ版の両方で行います。
- 『最終テスト』(出荷モード)
- 全て再コンパイル、リリース版のみ、デバッグツールをカット
- すべて手動テスト
- バグを直すことでコードを変更したら、
最後のテスト項目まで行った後、また最初から最終テストを行う。
- テストが通ったらベンチマーキング
基本的にテストケースは、仕様書に書かれていることそのままです。
開発期間全体を使って、随時テスト項目を作成していきます。
テストケースを欲張るとハマります。なるべく複合しないように選びます。
ホワイトボックステストは、テストケースを絞り込みます。
ブラックボックステストは、使用状況に合わせたものと、合わせないものにします。
トップダウンにテストケースを選び、内部のテストを兼ねるようにします。
テストするときのチェック項目は次のようなものがあります。
- テスト範囲
- 統合テスト(ブラックボックス)
- 単独テスト(関数テスト)(ホワイトボックス)
- 内部テスト(明示しなくてよいことが多い)
- 経験
- 最も新しく修正した個所
- 以前、不具合が見つかったケース
- 過去に作成したものの再確認
- ユーザが要求すること、またそれ以上の要求
- 再テスト
- ホワイトボックステスト
- 最も単純な正常な値について
- ユーザがよく間違える間違った値について
- すべての制御ルートについて
- すべての状態とイベントの組み合わせ
- すべての設定値について
- ブラックボックス・テスト(後でエラーのケースの入力値が確認できること)
- テスターが気になる特定のケース
- ランダムに抽出したケース
- 全てのケースの極値と統計値をチェック
- 別のアルゴリズムから求めた全てのケースとの比較
- 他人が作成したテストプログラム
- 値の範囲、値の格納場所
- 内部、外部の値がギリギリ範囲内、範囲外(無効値、入力無し)の場合
- 正常なエラー値について
- 正しい値を求めるのが難しい場合は、選択的なチェックでもよい
- 格納するアドレスのチェック
- 総数や平均値や最大値による判定
- コンテナに入っている要素の数が 0, 1, 多の場合
- 事前条件と事後条件の両方のチェック
- テスト環境
- 初期状態、リセット後
- 別のマシン環境
- 過負荷状態(リーソスが不足しがちな状態、要素数が異常に多い場合、
長い間走りつづけた場合)の耐久テスト
- マルチタスク環境、リエントラント
テストケースに対応したチェックリストを作成する。
なかなか解決しないものは後回しする。
作成したテストプログラムや、テストデータ、正常な出力データは取っておく。
自動テストは止まらないようにして、ログに記録する。
以下に、それぞれのテストケースのチェックの仕方を説明する。
『出力結果を直接見ることによるチェック』
- (概要)電卓や手計算によって、正しい値が正しい出力場所に
格納されているかを目でチェックする。
- (ケース)チェックする項目数が少ない場合。
正しい値を求めるのに手順が簡単な場合。
チェックプログラム(×テストプログラム)を作るまでもない場合。
- (準備)目で見える状態にするプログラムの信頼性が
十分にあるかチェックすること。その際、
別の出力媒体で比較する。正しい値は、自分で合っていると
考えたものを比較するのではなく、仕様と合っているか
どうかをチェックする。チェックする値は、ある曖昧な条件を
満たしているものの数や最大値最小値や平均で行ってもよい。
- (判定)正しい値と目に見える出力結果を目で比較する。
正しい値を試験仕様書か試験報告書に添えておく必要がある。
『出力結果の流用によるチェック』
- (概要)何らかの手段で正しい出力結果が得られた場合、
直接出力結果を比較する。
- (ケース)同じプログラムについて条件、環境が異なる場合が多い場合。
メモリなどのリークをチェックする場合。
- (準備)正しい出力結果は、まず、テストプログラムの出力を調べ、
後から手計算や電卓や表計算ソフトを使って正しさを確認する。
ただし、正しい出力結果は、テストプログラムが計算できる
ものであっても、1つ1つ値をテストプログラムの
中に持つこと。出力の値だけでなく、正しい出力する場所(アドレス)
もチェックするようにする。
テストプログラムのテストは必要。主な出力場所に間違った値を
正しい出力結果に入れてみる。
出力場所以外の場所にダミー値を入れておいて、その値が
変化しなかったことをチェックする。
- (判定)テストプログラムが通ったことを確認する。
テストプログラムの信用性と、正しい出力結果を、
試験仕様書か試験報告書に添えておく必要がある。
『別アルゴリズムによるチェック』
- (概要)まったく別のアルゴリズムの2つかそれ以上の
出力結果を比較する。
異なったアルゴリズムが同じ誤った結果を出す可能性は非常に
少ないことが確率的に言えるため。
- (ケース)チェックする項目が多い場合。
信頼性、実績のあるプログラムがある場合。
- (準備)別のアルゴリズムを流用するか作成する。
テストプログラム自体のテストは行わなくともよいが、
わざと間違った出力をさせて、間違いが検出できるかチェックする。
それぞれのアルゴリズムが完全に異なることを
チェックしなければならない。
- (判定)テストプログラムが通ったことを確認する。
アサートとは、作成しているプログラムのデバッグ版に
チェックコードを入れて、チェックすることです。
通常、デバッグ版とリリース版を
作成し、その切替えは NDEBUG が #define されているかどうかを
#ifdef 〜 #endif を用いて行います。
アサートは、クイックテストを行っていることと同じです。
C 言語の標準ライブラリに assert マクロがあります。
- 事前条件表明のアサート
-
処理の実行前に満たさなければならない条件をアサートします。
引数の定義域をチェックします。
- 事後条件表明のアサート
-
処理の実行後に満たさなければならない条件をアサートします。
出力の値域をチェックします。
- オブジェクトの正規条件表明のアサート
-
事前条件表明、事後条件表明のどちらにも共通に使えるチェックが、
オブジェクトの正規条件表明です。
オブジェクトの属性値に対してチェックするメソッドを作成します。
- 機能数、関数数、試験数などは、それぞれの要素の規模が異なるため
大体の目安でしかないことに注意
- 不具合一覧:日付、症状(正と誤)、修正点
主なものでいいから1つ2つ書く。
- テスターモジュールはコンポーネントと対応させる。
(なるべくリンクさせるモジュールは少なく)
- コンポーネントに状態の変化が無ければ、
あらゆるテスト・メソッドを以前のテスターモジュールに加えていく
- テスターモジュールは、サブ・ディレクトリにまとめるとよい。
- クリーンルーム手法
- スクラップ&ビルド
- 開発単位ごとに適切な開発方法そのものの改良
written by m.toda Jun.24.1997 〜 Aug.18.1997