実践 ICONIXプロセス : 単体テスト

テスト駆動開発(TDD)では、コードを書く前にテストコードを書きます。
ICONIXプロセスでは、コードを自動生成しますので、コードを書いてからテストコードを書きます。

ですから、全く別のアプローチ...

というのは真っ赤なウソです。表面的には正反対に見えます。本質は、テストすべきことを明確にしてから、コードを書く点で同じアプローチです。

テスト駆動開発(TDD)では、テストすべきことをテストケースとして「設計」します。では、その設計の情報源はなんでしょうか?
なんらかの分析モデル、設計モデルを使うことになるのでしょう。まちがった XP 流儀だと参考になるモデルがない状態で、テストケースをひねり出す魔法が必要になります。思いつたことからコーディング?
テストケースを作るために、ヒアリングやモデリングをするというのは、一つの方法論だと思います。でも、結局、テストコードを書く前にモデリングをすることになります。

ICONIXプロセスでは、単体テストのテストケースは、ロバストネス分析の結果をそのまま利用します。ロバストネス図のコントロールが、そのままテストケースです。
テストケースの設計は、予備設計として、詳細設計より前に終わっている作業です。

単体テストのため、いつ、何をやるかは単純明快かつ実践的です。

・テストケースの洗い出しは、ロバスト分析時に終了(コントロールとして定義)
・詳細設計後の詳細クラス図からコード(の雛形)を自動生成
・テストケースごとにテストコードを書く
・テストを実行して失敗(まだコードの雛形だから)
・コードを実装
・テストを実行して成功

ようするに、テストコードを書くためのテストケースは、ロバストネス図で描いたコントロールとして設計済み、ということです。エディタの前で、テストケースに頭をひねるより実践的でしょ?

ロバストネス図とテストコードを比べれば、ロバストネス図は絵ですからテストケースの構成や順番がとてもわかりやすい。
単体テストが不足していないか、単体テストをやりすぎていないか、などの単純にロバストネス図のコントロールとテストケースを付き合わせればチェックできる。この作業をもっと楽にやるために、ロバストネス図から、テストケース図を自動作成するアドインツールもあります。( Enterprise Architectのアドイン)

実践 ICONIXプロセス : NGこそ正解

ソフトウェアをテストする前に準備しておくこと。

・解答付き問題集
・テストデータ

解答付き問題集

テストをやるには、問題が必要です。それも解答付きの問題集を準備する。

性能テストで、性能の測定結果だけのテスト報告書を見たことがあります。合格したのか、不合格かの判定結果がない。そもそも、どこが合格ラインか事前に決まっていない。

単体テスト、統合テスト、システムテストなど、どんなテストでも、これと同じことがおきがちです。テストという作業はしているが、判定基準が決まっていないか、きわめて曖昧。

例えば、入力画面のテストで、漠然と、すべての項目にそれらしいデータを入力して、登録ボタンを押して、エラーにならなければ、OK、というようなパターン。

このようにOKケース(晴れの日のシナリオ)中心のテストは、たいていの場合、時間のムダ。
開発者は多かれ少なかれ無意識にOKになるようにデータを入力し、操作するから。
(そのチェックするやらないのは論外です)

模範解答はNGケース

NGケース(エラーを起こす)は「正解」です。

OKケースが正解なのは当たり前ですが、NGケースこそ正解です。

想定したNGケースを実行し、予定通りにエラー処理をしていることを確認する。これがテストの基本です。
駆け出しの技術者とベテランの発想の違いがとても良くでる場面ですね。

NGケースを発生させること、そして、予定通りのエラー処理ができたことを確認することがテスト作業の大半を占めます。

ユースケースの代替コース

ICONIXプロセスのガイドブックでは、繰り返し、ユースケースモデリングの「代替コース」の洗い出しを強調しています。

ユースケースを記述する時、要求レビューの時、ロバストネス分析の時、予備設計レビューの時、詳細設計の時、詳細設計レビューの時、コードを書くとき、コードレビューの時。

すべての作業段階で繰り返しやるべきことが「代替コースの洗い出し」です。

ICONIXプロセスでは、コードができあがったときには、これだけ念入りに作成しレビューした強靭な「代替コースのセット」があります。

解答付き問題集、それも、いちばん重要なNGケースを網羅した解答付き問題集がすでに完成しているわけです。
あとは、この問題集をやりながら、答え合わせをすれば良いわけですね。

テストデータ

・画面から入力するデータ
・データベース上に準備するデータ
・テストコードに埋め込んだデータ
・モックアップに埋め込んだデータ
・入力ファイルのデータ
...

テスト、特に業務系のアプリケーションのテストでは、テストデータの設計と実装が中心課題です。

この場合も、最低限のOKケース用のデータだけ用意ということをやりがちです。

いかにNGケース用のデータを用意するか?
これも、NGケースを事前に洗い出してあれば、比較的容易な作業です。

テストデータの設計という独立した仕事でやろうとしても、そう簡単にはNGケースの洗い出しはできません。

ユースケースから始まる一連のプロセスで、繰り返しNGケースを洗い出して検証してあれば、NGケース用のデータもおのずと固まってきますね。

実践 ICONIXプロセス : バグの発見は勝利

リリース後にバグが発覚することは敗北です。
テストで、リリース前にバグを発見できたら大勝利です。

バグが必ず混在し、また、つぶしてもどこかに残っています。ゼロにはできない。

でも、やることをやっていれば見つけられたバグが、リリース後に発覚するのは情けないし、プロとして恥ずかしい。

やることをやった上で、それでも残ってしまったバグは、それはしょうがない。
人間ですから、完全なものはできません。

重要なのは、やるべきチェックや検証をちゃんとやっていたかどうか。

ソフトウェアの開発途中のバグの発見は、大勝利なんです。やるべきことをやっている証拠だから。
(バグが発見できないテストは、とても怪しい)


実践 ICONIXプロセス : DDT と TDD

ICONIXプロセスのテストのアプローチは、DDT( Design Driven Test, 設計駆動テスト)です。
XPだと、TDD ( Test Driven Development, テスト駆動開発 )ですね。

DDT と TDD は、文字が並びが逆ですね。(おそらく TDD への皮肉をこめている)

両方とも、コーディングの前にテスト仕様を考える、という点で、実は同じことを言っているように思う。でも、ICONIXプロセスの提唱者は、XP/TDDにはかなり批判的ですね。

おそらく、XP/TDDの信奉者たちに、分析・設計不要、と勘違いしている人が多いことを気にしているだと思います。
実際には、XPも、モデリングはとっても重視しているんですけどね。コードを書く前の分析・設計は当たり前です。意味もないドキュメント作成は無意味ですが。

良いソフトウェアの作り方に本質的な違いがあるわけではなく、表面的なテクニックや用語が違うだけなんだと思います。ただ、用語が違うと、本質論より、表面的な違いを重大視した不毛な議論がおきがちですが...

実践 ICONIXプロセス : 設計駆動とV字モデル

テストのV字モデルは、古典的なウォータフォール式のやり方で、最近はあまり良い意味では使われない気もします。

確かに、山のようなテスト計画書、テスト仕様書、テスト報告書、などヘビーなドキュメントワークは実践的ではないですね。
単純なWebアプリケーションを、短期間で作るのには現実的ではない。

しかし、だから、テスト用のドキュメントが無くて良い、とか、V字モデルのさまざまなテストが不要、というのは短絡すぎる。

ICONIXプロセスは、事前にテストの仕様があり、V字型にテストすることは、とても大切だと考えます。
ただし、それを実践的にアジャイルにやることを重視する。

V字の一番底をコーディングとすると、テストのV字モデルは、次のようになります。

・詳細設計  単体テスト
・予備設計  統合テスト
・ユースケース  システムテスト
・要求事項  受け入れテスト
・ビジネスケース リリーステスト

この他、開発プロセスを通じて行うべきテストとして

・非機能要求テスト
・パフォーマンステスト
・ストレステスト
・ボリュームテスト

をあげています。

そして、テストの開始時期は、コーディングのずっと前から始まります。

例:

あるシステムの開発を企画するために、ビジネスでの利用の仕方(ビジネスケース)を検討している時、それは、リリーステストのテストケースの設計である。

こういう感覚です。

実践 ICONIXプロセス : 設計駆動テスト

ICONIXプロセスは、ユースケースをコードに落とし込むプロセスです。
テストについても、ユースケースから単体テストコードに落とし込む(そしてテストする)ことが中心です。
著者たちは、XP というか「テスト駆動開発」には、だいぶ批判的なようです。

JUnit を使って単体テストを自動化する、という点では同じように見えます。ICONIXプロセスでは、どうやって単体テストのテストケースを作成するか、に主眼が置かれていて「テスト駆動開発」には、それが欠けている、という点を問題視しています。

ガイド本「ユースケース駆動開発実践ガイド」の12章「設計駆動テスト」には、単体テスト以外の広い視点のテスト論やテクニックもでてきます。

単体テスト、統合テスト、システムテスト、受け入れテスト、リリーステスト
非機能要求テスト、パフォーマンステスト、回帰テスト、ストレステスト、ボリュームテスト

これらのテストを、正しいタイミングで実施することがたいせつ。

もちろん、ICONIX流なので内容は、

・実践的
・設計重視(事前に定義しておくことを重視)

です。

実践 ICONIXプロセス : モデルと同期する

コードを書きはじめると、コードの世界だけに没入しがち。

コードレビューや、リファクタリングでコードを修正したら、必ずモデルと同期をとりましょう。

ユースケース記述との同期

コードは、ユースケースを実現するためにあります。
ユースケースのアクションステップを実現するのは、どのクラスの責務で、どのメソッドを使うかのチェックを必ず行いましょう。

詳細クラス図との同期

設計は、コードで表現できていますが、詳細クラス図でも表現しましょう。
コードと絵という異なる方法で表現すると、問題点を発見しやすくなります。

コードと詳細クラス図との同期は、Enterprise Architect などのモデリングツールを使えば、意外と簡単です。

コードを更新して、同期をとると、詳細クラス図を自動的に更新できます。
そして、更新結果を詳細クラス図という別の視点で見直すと思わぬ発見があります。

---

ICONIXプロセスの品質確保の考え方は、

・複数の表現方法を使って、照らし合わせる
・複数のメンバーの視点でチェックする

の2点です。

実践 ICONIXプロセス : コードのチェックリスト

私の個人的なコードレビューのチェックリストです。

3行ルール

3行を超えたら、改行する。別ブロックにする。
import 文にはじまり、フィールドの宣言、メソッド内のロジック、if ブロック内のコード、どこでも、連続していいのは、3行まで。

3行を超えていたら、グルーピングを考える。
5行以上、改行やブロックの区切りがなかったら、まちがいなくNG。

メソッドでくくり出したり、2つ3つの変数を持つ小さなオブジェクトを設計するなりするべき。

重文禁止

if 文で、 || や、&& で評価式を連結するのは禁止。
最低限、評価メソッドで外だしにする。
評価メソッド内でも、原則使わない。

重文はバグの巣ということを経験的に分かっているから。(特に修正時)

複文禁止

object.get().get().get() は禁止。
3つの文に分解する。それぞれの get() メソッドで取得するオブジェクトを一次変数で明示する。
変数名はもちろん、意味のある名前をつける。

入れ子の禁止

if文のなかの if文。
if文のなかの for文。
for文の中の if文。

メソッドでくくりだすことを考える。
入れ子もバグの巣であることを経験で知っているから。

ゼロパラメータ

メソッドのパラメータは、ゼロが最も良い。

2つ以上だったら、一つのオブジェクトにカプセル化することを考える。

一つだけのパラメータは、そのパラメータのオブジェクトにメソッドを移動すると、ゼロパラメータになる。

クラスの責務設計、メソッドの割当が洗練されてくると、ゼロパラメータのメソッドが増えます。

パラメータがずらっと並ぶメソッドは、アンチパターンです。

名前はフルスペル

パッケージ名、クラス名、メソッド名、フィールド名、一次変数名、すべてフルスペルで書く。
習慣的な短縮形も使わない。(悪い習慣)

他の人の短縮形を理解できずに保守に苦しんだことが何回もあるから。

コメント禁止

名前をフルスペルにしても、まだコメントが必要?
名前がたぶんおかしい。

まあ、英語の訳語を注釈することが良い時があるかもしれない。

calendar
   1234
567891011
12131415161718
19202122232425
262728293031 
<< October 2008 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM