この記事はTDD Advent Calendar jp: 2012 : ATNDへの参加エントリーです。昨日は@nnasakiさんの「デシジョンテーブルを使用してテストしてみよう #TddAdventJp – nnasakiのブログ」でした。
TDDにおけるIDEの重要性
TDDを進めていく中で、一番注力したいことは@irofさんもおっしゃっていましたが、「思い通りに動くコードを書くこと」です。
しかし、思ったことを書こうとしても「この変数が欲しいな」、「名前が不適切だから変えよう」などなど、単純だけど少し手間な作業が案外プログラミングには多いものです。こういったものは、ツールに任せてしまうのが一番です。
幸い昨今のIDE(統合開発環境)は非常に優秀ですので、文脈(コンテキスト)を踏まえた変換処理などもお手の物です(エディターとは違うのだよ、エディターとは!)。これを使わない手はありません。
IDE活用の実例
では、実際にIDEをフル活用してTDDを行っていってみましょう。今回使用するのは、Visual Studion 2012、および無償の拡張ツールであるCodeRush Xpress、Quick Test Switcherで、言語はC#です。
題材は「車窓からのTDD」を選びました。C#用に、以下ように仕様を微調整しました。
- bool IsEmptyプロパティ
スタックが空の場合、true。それ以外false を返す。
- int Sizeプロパティ
スタックのサイズを取得する。
- void Push()メソッド
引数の値をスタックの一番上に積む。
- void Pop()メソッド
スタックの一番上の値を取り除く。
スタックが空の場合、EmptyStackExceptionが発生する。
- int Topプロパティ
スタックの一番上の値を取得する。
スタックが空の場合、EmptyStackExceptionが発生する。
プロジェクト作成
コードを書き始める前に、器となるプロジェクトを作成しておきましょう。次のように、プロダクトコード用のTddFromTrainWindowと、テストコード用のTddFromTrainWindow.Testプロジェクトを作成しておきます。
- TddFromTrainWindow
- TddFromTrainWindow.Text
- 単体テストプロジェクト
- TddFromTrainWindowプロジェクトを参照している
なお、「TddFromTrainWindow”.”Test」としているのは、”.”で名前空間を区切ることで、テストコードでは上位の名前空間の型がそのまま参照可能になるからです。
また、テストコードが自動で実行されるよう、[テスト]メニュー→[テスト設定]→[ビルド後にテストを実行]を有効にしておきましょう。
StackTest、Stackクラスの作成
それでは実装を進めていきましょう。まずはStackTest、Stackクラスのペアを作成します。
- Ctrl+Shift+Aで「新しい項目の追加」ダイアログを開き、[基本単体テスト]を選択して”StackTest”として作成する。
- StackTestクラスのTestMethod1メソッドをTestCreateにリネームする。
- new Stack();までタイプしたところでCtrl+.を押し、[新しい型の生成]を選択してTddFromTrainWindowプロジェクトにStackクラスを作成する。
- テストコードとプロダクトコード間の移動はQuick Test Switcherの機能を利用して行う(ショートカットキーはCtrl+9に事前に変更済み)。
Stackオブジェクト作成直後はスタックが空であることのテスト
IsEmptyプロパティを追加し、Stackオブジェクト作成直後が空であるよう実装します。
- new Stack();の行でCtrl+@キーを押し、[Declare Local]を選択してstack変数を作成する。
- stack.IsEmptyプロパティがTrueであることの確認コードを書く。
- IsEmptyプロパティにてCtrl+@キーを押し、[Declare Property]を選択してIsEmptyプロパティを作成する。
- ここで一度Ctrl+Shift+Bキーを押してビルドし、テストが実行されて失敗することを確認する。
- IsEmptyプロパティでF12キーを押し、実装に移動する。
- テストを通すため、IsEmptyプロパティの実装をreturn true;にする。
- ビルドを行い再度テストを実行し、テストが成功することを確認する。
Stackオブジェクトの初期化処理をSetUpメソッドに移動
Stackオブジェクトは間違いなく他のテストでも使うので、フィールドにしてSetUpメソッドで初期化するようにします。
- stack変数でCtrl+@キーを押し、[Widen scope (promote to field)]を選択してstack変数をフィールドに昇格させる。
- stackフィールド初期化処理行を選択してCtrl+@を押し、「メソッドの抽出」ダイアログを利用してSetUpメソッドに切り出す。
- SetUpメソッドにTestInitializeAttributeを付ける。
- SetUpメソッドをpublicに変更する。
- ビルドしてテストを実行して成功することを確認する。
Push後のTopでPushした値を取得
PushとTopを組み合わせたテストケースを作成し、フェイク実装でテストが成功するところまで実装します。
- testmまで入力したところで、TAB、TABと2回キーを押し、コードスニペットからテストケースの雛形を挿入する。
- メソッド名をTestPushAndTopに変更し、Enterキーを押す。そうすると、テストケース本体にカーソルが移動する。
- テストケース本体を入力する。
- 未定義のTopプロパティ、Pushメソッドの空実装をCtrl+.で作成し、ビルドしてテストが失敗することを確認する。
- Topプロパティのフェイク実装(return 1;)を行い、ビルドしてテストが成功することを確認する。
フェイク実装の箇所をPushで与えた値を返すようにリファクタリングします。
- PushメソッドでF12キーを押し、定義に移動する。
- PushメソッドのパラメーターpでCtrl+@キーを押して[Rename]を選択し、名前をvalueにへんこうする。
- this.value = value;と入力し、Ctrl+.キーを押してvalueフィールドを生成する。
- valueフィールドの定義に移動して確認する。
- Ctrl+-キーを押してカーソル位置を復元する。
- Topプロパティをreturn this.value;に変更する。
- ビルドしてテストを実行し、成功することを確認する。
以後の実装
同じように各種ショートカットキーなどを駆使しつつ進めていきます。
それぞれ動画で確認してみてください。
(後で追加しておきます。)
まとめ
これまで見てきたように、IDEにはコードを書くための補助機能がたくさんあります。その中にはコードの自動生成など、TDDを進めていくうえで無くてはならないものも含まれています。
IDEを使いこなしていけば、より一層本来の「思い通りに動くコード」を書くことに集中できるようになれるでしょう。
明日は@ktz_aliasさんにバトンタッチです。
Rhino.Mocksをちょっとだけ幸せにするお助けクラス – Since 1975