テスト駆動型開発(TDD)とグレーボックステスト

最近、テスト駆動型開発(TDDあるいはBDD)についての雑誌を買ったり他のブログに感化されたりしたので軽い考察を。

==

実装とテストを繰り返しながら設計をすすめる、といった形でコーディングするとき、みなさんはどんな手順ですすめますか?僕はこんな感じでやってます。(僕はC言語をベースに開発することが多いので、C言語をサンプルに)

  1. 骨組みだけの関数を作成する


  2. /**
     * func1(); ○△×をする関数
     * 引数
     * 復帰値
     * 0 正常
     * -1 エラー
     */
    int
    func1(
      const char* str1,
      char* ptr2,
      int num3 )
    {
      return(-1);
    }

    モジュール設計に基づいた関数の骨組みだけを記述する。ただし、復帰値がvoid以外ならばエラー復帰をまず記述しておく。


  3. テストスイートを作成する


  4. - 引数チェック
    - 正常系ケース
    - 限界値ケース
    - エラーケース
    - 異常系ケース

    テストスイートは複数のテストケースの集まりをあらわし、「引数チェック」「正常系ケース」「限界値ケース」「エラーケース」「異常系ケース」といったテストケースを作成する。引数チェックは、関数の引数にNULL、0、負の数、ヌル文字のポインタ(””)などを指定した場合に正しく引数エラーを返すかどうかを確認する。正常系ケースでは、尤もらしい動作をするであろう条件を指定する。最低でもひとつ、そしてコーディング後に追加するのもあり。限界値ケースは、条件の境界値(最大値、最小値)において正常な動作をすることを確認する。これは正常系ケースと兼ねてもいい。エラーケースは、尤もらしいエラーが発生する条件を指定し、エラーが発生することを確認するテストケース。異常系ケースは、今までの4群以外で、例えば非常に大きなデータや、言語上の限界値などを指定する。

    これらのテストケースをまとめる際、仕様書の欠陥などを同時にレビューするのもよい。


  5. テストを実行する
  6. 骨組みだけの関数をコンパイルし、テストスイートにある条件&評価でテストする。僕の場合はMinUnitというマクロをベースにテストコードを自動生成して、「-fprofile-arcs -ftest-coverage」をオプションにしてコンパイル&実行する。

    ちなみに、ほとんどテストケースは失敗に終わり、いわゆる「レッド」の状態。



    /* file: minunit.h */
    #define mu_assert(message, test) do { if (!(test)) return message; } while (0)
    #define mu_run_test(test) do { char *message = test(); tests_run++; \
                if (message) return message; } while (0)
    extern int tests_run;

    -fprofile-arcs -ftest-coverage」をオプションにするのはあとでgcovでカバレッジ測定をするため。


  7. テストケースをクリアするように実装をすすめる
  8. 対象となる関数を実装していき、テストケースが「グリーン」にしていく。このとき、実装とともに必要と思われるテストケースを追加していくのもあり。


  9. テストスイートがクリアすることと、カバレッジ率を80%以上に保つ
  10. テストケースをすべてクリアすることと同時に、ステートメントカバレッジにも着目すること。僕の場合は、目安は80%~95%を目標にする。


本当は「リファクタリング」も必要なのだが、とりあえずこんな感じで試しているところ。

==

さて、こういったテストファーストで実装していくこと得られるメリットは、というと、、、

  1. ユニットテストケースがグレーボックスっぽい
  2. 境界値や異常系を考慮するので、グレーボックス的なアプローチができる。

  3. 引数チェックでブラックボックスっぽい
  4. 引数チェックは境界値やエラー推測といったブラックボックス的なアプローチができる。

  5. 仕様書の見える化、掘り起こしができる
  6. テストケースを作成するプロセスは、仕様を浮き彫りにする作業となる。

ただし、いいことずくめではないと思っていて、引数が多くなったり、複雑な処理になるにしたがって、テストケースは膨れ上がる。テストをグリーンにするために実施カバレッジは少なくとも100%にする必要もある。だから、どこかで手を打たなくちゃならない。その基準は、まだよくわからない。


| | コメント (0) | トラックバック (0)

ブラックボックステストは、缶詰とビン詰か

昨日のグレーボックステストについての続き。というか思いつき。

==

ブラックボックステストといっても、全くソース構造を知らないままで行う真っ黒なブラックボックステストと、ソース構造を把握した上で(例えば実装担当者がテストケースを作成する場合など)行うブラックボックステストでは、手法・効率・精度などで違いが出てくる。一般的に前者は「ブラックボックステスト」と呼ばれ、後者は「グレーボックステスト」と呼ばれる。

そこで。

高校のときに見た(確か旺文社の問題集)名前付けを思い出したのだが、「缶詰テスト」「ビン詰テスト」という表現はどうか。「缶詰」は中身が全くわからない。「ビン詰」は中身が一応見える。でも両者ともに機能は一緒。

名前なんてどうでもいい、か。。

| | コメント (4) | トラックバック (0)

グレーは白と黒をあわせたもの?

今日は休暇。久しぶりにまともな更新。

==

ふと、グレーボックステストってどういうものだろう?と思って調べてみた。

第13回 「ソフトウェアテストの設計 その5」

ある程度、作りが分った上で実施するテストをグレーボックステストといいます。

(中略)

グレーボックステストはアーキテクチャが分っていることに意味のあるに時に用いるやり方で、ユーザビリティテストの様に仕組みを知ることがかえってマイナスとなるテストでは適用すべきではありません。「こう作っているのだから、そう動くべきだ」という見方と、「こう使いたいのだから、(作りがどうであろうと)そう使えるべきだ」とでは検証で目指すところが違うからです。

この定義だと、ホワイトボックステストでもなく、ブラックボックステストでもない検証項目、といったイメージ。ホワイトボックステストケースとブラックボックステストケースを優先順位で並び替えた総合テストケース群、ということではない。

しかしだ。

例としてABS(アンチ・ロック・ブレーキ・システム)の動作確認をするケースで考えてみましょう。構成を何も知らず、要件として「ABSスイッチがONの時は、急ブレーキをかけてもタイヤがロックしないこと」ということだけを知っていて、検証するケースがあるとします。

この場合と「ABSスイッチがONで、時速XXkm以上にて走行時、踏力XX㎏以上でブレーキングされ、タイヤのロックがセンサにより検出された場合にはABSを作動させる...」という仕様をテストで確認するケースとでは、検証の詳細度がかなり異なります。

グレーボックスは後者に当たり、

ここでは「ABSスイッチがONで、時速XXkm以上にて走行時、踏力XX㎏以上でブレーキングされ、タイヤのロックがセンサにより検出された場合にはABSを作動させる...」をグレーボックス的なテストケースと位置づけている。

でも、これはABSスイッチの状態、走行速度、ブレーキの踏力、センサーの感知といった条件での動作確認であって、仕様書に載っている条件と思われる。それってブラックボックステストケースになるんじゃ?

黒と白の中間」と表現されることが多いグレーボックステストだが、意外にわかりにくい定義な気がする。

==

今、自分なりのTDDっぽい開発をしているが、そこでのテストケースはグレーボックスだなあと思っている。が、それってもしかしたら黒と白をあわせただけのテストケースなのかも。これってどうなのだろうか。

====================================================================
2006年11月29日 追記。

JUnitと単体テスト技法―JUnit4対応 by それはBooks

このブログではコンピュータ書籍, デザイン書籍, ビジネス書籍, その他の書評を行っているようで、

このJUnit の使い方と単体テストについての書籍中では以下のように解説している。

ブラックボックステスト

 ブラックボックステストは、プログラムの仕様を元にテストを行うものです。プログラムの内部構造は考慮せず、入出力の仕様に注力します。
 ブラックボックステストとして、次の4つのテストがあげられています。

  ・同値クラステスト
  ・境界値テスト
  ・デシジョンテーブルテスト
  ・強制エラーテスト
  ・グレーボックステスト

ここではグレーボックステストは、ブラックボックステスト技法のうちのひとつになっている模様。


| | コメント (2) | トラックバック (0)