.NET Tools
NUnit入門 Test Firstのススメ
3.NUnitを実行する
(株)ピーデー
川俣 晶
2002/02/23 |
 |
まず、[スタート]メニューの[プログラム]−[NUnit]−[NUnitGUI]を実行して、GUIバージョンの「NUnitランナー」を開こう。そして[Browse]ボタンをクリックし、たったいまビルドしたEXEファイルを選ぶ。ダイアログを開いた時点ではDLLファイルしか見えない設定になっているので、肝心のファイル(今回はEXEファイル)を見落とさないように注意しよう。ファイルを選ぶと、上から2番目の欄の[Type Name]の横に、“MyGame.HighScoreTest”というクラス名が入る。これは紛れもなく、たったいま作成したテスト・クラスの名前である。NUnitが自動的に探し出して設定してくれたものなので、ここではそのまま使えばよい。ちなみに、こういうテスト・クラスはテスト・スイートとも呼ばれ、1つのプログラムに複数含めることができる。[Type Name]の設定は、複数のテスト・クラスが存在するときに、どれをテストするかを指定するものである。
 |
NUnitランナーの起動画面 |
[Browse]ボタンをクリックし、ビルドして出来上がったEXEファイルを指定する。これにより[Type Name]の部分に、先ほど作成した“MyGame.HighScoreTest”というクラス名が自動的に入る。 |
|
 |
ビルドにより作成されたEXEファイルを指定する。 |
|
 |
このボタンにより に指定するファイルをファイル・ダイアログから選択できる。 |
|
 |
EXEファイルを指定すると、それに含まれるテスト用のクラスが列挙される。 |
|
 |
このボタンをクリックするとテストが開始される。 |
|
さて、いよいよテストの実行だ。[Run]ボタンをクリックしよう。
 |
テスト実行後のNUnitランナーの画面(1) |
まだHighScoreクラスの実装を行っていないため、Assertの失敗が表示されるが、これは間違いなく失敗を失敗として伝える能力があることを証明している。 |
|
 |
発生した例外などのエラーやAssertの失敗がここに表示される。 |
|
 |
のリストで選択した項目について、ソースのファイル名や行番号などの詳細情報がこちらに表示される。 |
|
赤い部分(プログレス・バー)のすぐ下にあるタブに注目していただきたい。ここに、「Errors(0) and Failures(3)」と表示されている。これは、ファイルが見つからないといった例外で示されるエラーが0件、Assertの失敗が3件あることを示している。その下に具体的に失敗した内容がリストされている。リストから項目を選ぶと、詳細情報がさらにその下に表示される。この画面写真では、TestConstructorメソッドで失敗が起きており、「highScore.name == "NoName"」というメッセージが出力されている。その詳細は下に表示されている。画面写真では分かりにくいが、右にスクロールさせると、ソースのファイル名と行番号が表示されている。これにより、具体的に、どこのAssertが失敗したのかを知ることができる。
Assertが失敗するのは当たり前である。何しろ、実装はまだ何一つ書き込んでいないのだ。だがこれは無意味な失敗ではない。なぜなら、テスト・メソッドにバグが入り込んでいて、失敗するはずの条件を正しいと誤判断する可能性があるからだ。何も実装が含まれないクラスをテストして、テスト・メソッドの数と同じ数だけ失敗が報告されることが確認できれば、テスト・メソッドは間違いなく失敗を失敗として伝える能力があることを証明できる。間違ったメソッドを正しいと報告してしまったりしないと自信を持つことができるのである。もちろん、これは100%完全な確信ではないが、何もしないよりははるかに信頼性が高い。
プログラムを実装する
いよいよ、本来のプログラム・コード実装の本番である。一見回りくどいことをやってきたように見えるかもしれないが、ここまで進んでくれば、具体的にどう実装すればよいか、イメージできているはずだ。
まずは、TestConstructorメソッドを正しくパスするように、HighScoreクラスを書き換えてみよう。
1: using System;
2:
3: namespace MyGame
4: {
5: public class HighScore
6: {
7: public string name = "NoName";
8: public int point = 0;
9: public void setScore( string name, int point )
10: {
11: }
12: public bool isHighest( int point )
13: {
14: return false;
15: }
16: }
17: } |
|
メンバ変数を初期化するようにしたHighScoreクラス |
TestConstructorメソッドでのテストを正しくパスするようにコードを追加した。 |
TestConstructorメソッドが必要としているのは、メンバ変数に初期値を与えるだけなので、コンストラクタを作るまでもなく、「= "NoName"」や「= 0」といった初期化コードを直接書き込んでしまえばよい。あまり悩むような話ではない。相変わらず裸の変数がpublicになっているのが気になるが、当面、ほかに気になることが山ほどあるので放置しておこう。
書き終わったらビルドして、もう1度NUnitのGUIランナーを開いてテストを実行してみよう。
 |
テスト実行後のNUnitランナーの画面(2) |
失敗の数が1つ減り、TestConstructorメソッドの名前がリストから消えている。 |
|
 |
Assertの失敗を示すFailurerの数が2つに減っている。 |
|
 |
選択されている失敗は、変数highScore.nameの内容が“Taro”となっていないことを示している。 |
|
失敗の数が1つ減り、TestConstructorメソッドの名前がリストから消えていれば作業は成功である。作業が一歩先に進んだわけだ。
あとの2つの失敗も、さっさとコーディングして消してしまおう。実際に書いてみたのが以下のソースである。
1: using System;
2:
3: namespace MyGame
4: {
5: public class HighScore
6: {
7: public string name = "NoName";
8: public int point = 0;
9: public void setScore( string name, int point )
10: {
11: if( this.point >= point ) return;
12: this.name = name;
13: this.point = point;
14: }
15: public bool isHighest( int point )
16: {
17: return this.point < point;
18: }
19: }
20: } |
|
メソッドの内容を修正したHighScoreクラス |
残る2つのテストもパスするように、メソッドに処理を加える。 |
すべてのテストを満たしていれば、以下のようにプログレス・バーの色は赤ではなく緑になっているはずである。
 |
テスト実行後のNUnitランナーの画面(3) |
すべてのテストがパスするとプログレス・バーの色が赤から緑になる。 |
|
 |
テスト結果の状態を示すプログレス・バー。 |
|
 |
エラーの数も失敗の数も0になっているのが分かる。 |
|
これでハイスコア・クラスは完成である。このハイスコア・クラスに必要な機能が何であるかは、すべてテスト・クラス上に記述されている。従ってテストによってエラーが1つも発生しないということは、これにより必要な機能がすべてそろっていると見なせる、ということである。もちろん、テスト・クラスがいい加減なら、完成とは見なせないかもしれない。クラスの実装を確実にするためには、クラスが満たすべき重要な条件については、すべてテスト・クラスに書き込んでおく必要がある。
従来のコーディング優先のプログラミングでは、この段階に達して初めて、作成したコードが正しく機能するかどうか、あれこれと使ってみてテストするわけだが、今回のケースでは、すでにテストは終了してしまっているのである。早く家に帰って風呂にでも入ろう。しかし、本当にこれで一般的なプログラミングよりも時間の節約になっているのだろうか? 残念ながらこれまでの段階では、必ずしも時間の節約にはなっていない。テストに要する時間を先に使っているからだ。
Insider.NET 記事ランキング
本日
月間