« [イベント] 告知 - Tech Fielders セミナー 東京 [Agile Day 「A Start - アジャイル開発が気になるあなたに贈るセッション&ワークショップ] ( 1/22, 新宿 ) | トップページ | [記事紹介] ZDNet Japan ~ ソフトウェアの新たな開発手法、「アジャイル開発」って? »

2010年1月 7日 (木)

[コラム] [VS2010] 新機能 Generate From Usage (使用法から生成) の使い方 Step by Step

Visual Studio 2010 の新しい機能である "Generate From Usage" ( 使用法から生成 ) について、 そのチュートリアル記事を以前に紹介したことがあります。
そのチュートリアルは、 英語版の CTP に基づいて書かれています。 日本語版の Beta 2 でも基本的には同じですが、 改めて手順を C# で紹介してみます。

VS2008 にはメソッドの生成機能があります。 それは自動生成したコードの方にカーソルが移ってしまうので、 TDD しているときにはテストケースを書いている流れを邪魔されてしまっていました。 VS2010 では、 その点が改善されただけでなく、 クラスの生成機能も追加されています。

興味を持たれたかたは、 Beta 版 (2月には RC 版が公開されるようです) を入手して試してみてはいかがでしょう。 なお、 この機能は Express Edition には搭載されないようですので、 Beta 2 では Ultimate エディション日本語版を使ってください。
※ (2011/2/10 追記) C# 2010 Express にも (VB 2010 Express にさえも!) 搭載されています。

 

◆ STEP-1: プロジェクトを用意する

まず、 これから作成する製品コードが入るプロジェクトを作ります。
なんでも良いのですが、 ここではコンソール アプリケーションにしてみました。 プロジェクトの名前は ConsoleApplication1 としました。 自動生成された Program.cs ファイルには、 ConsoleApplication1 というネームスペースが定義されています。
※ ネームスペース ConsoleApplication1 がすでに存在していることを、 覚えておいてください。

続いて、 テストコードを入れるプロジェクトを作ります。
ソリューションにプロジェクトを追加するときに、 「テスト プロジェクト」 を選んでください。 プロジェクトの名前は ConsoleApplication1Test としました。 プロジェクトが生成できたら、 ConsoleApplication1Test プロジェクトの参照設定に、 ConsoleApplication1 プロジェクトを追加しておきます。

20100106_generatefromusage01
ここまでで、 ソリューション エクスプローラーの状態は上図のようになっています。

 

◆ STEP-2: テスト クラスを用意する

ConsoleApplication1Test に自動生成された UnitTest1.cs の名前を変更します。 これから作成する製品クラスを Foo としましょう。 そのテストクラスということで、 UnitTest1 を FooTests にリネームします。
また、 自動生成されたテスト メソッドは TestMethod1() という名前になっています。 本来はこのメソッド名も、 テストケースの意味が分かるように改名するのですが、 ここではそのままでいいことにします。

 

◆ STEP-3: クラスの生成を試してみる

それでは、 製品クラス Foo のテストケースを、 FooTests.cs の TestMethod1() の中に書いていきます。
まずはコンストラクトするところを、 ネームスペースから書き下してみます。

ConsoleApplication1.Foo foo = new

まで打ったところで…
20100106_generatefromusage02
VS2010 の新しいインテリセンスが、 まだ存在していない ConsoleApplication1.Foo を提案してくれます。 等号の左側に打ったネームスペースとクラス名を、 見てくれているのですね。
※ これは 「使用優先 モード」 と呼ばれます。 インテリセンス ウィンドウが開いているときに Ctrl + Alt + スペースキーを押すと、 標準モードとの間で切り替えができます。
※ ConsoleApplication1 ネームスペースが存在しない場合は、 ConsoleApplication1 のほうに赤い波線が引かれ、 自動生成できません。 また、 クラスを自動生成されるときに、 ネームスペースの指定をすることもできません。 どうやらネームスペースは自動生成の対象外で、 あらかじめ作っておく必要があるみたいです。

提示された ConsoleApplication1.Foo を選んで打ち続け、 1行完成させます。

ConsoleApplication1.Foo foo = new ConsoleApplication1.Foo();

クラス Foo は存在していませんから、 "Foo" の下に赤い波線が表示されます。
行末の "Foo" にマウス カーソルを持っていくと…
20100106_generatefromusage03_2
「選択した項目をバインドするオプション」 というスマートタグが現れます。
このスマートタグをクリックしてみると…
20100106_generatefromusage04
2つの選択肢が提示されます。

  • 'Foo' のクラスを生成する
  • Generate new type...

※ "Generate new type..." は、 製品版では日本語になるでしょう。

この選択肢は、 "Foo" にカレットを置いて右クリックしても出すことができます。 コンテキストメニューの [生成] を選べば…
20100106_generatefromusage05

  • クラス
  • New type...

と、 選択肢が出てきます。
※ スマートタグとは表現が違います。 これは製品版では …直ってないかもしれません。

この 2つの選択肢には、 大きな違いがあります。

  • クラス
    必ずこのコードと同じプロジェクト内に、 クラスを作ります。  (ネームスペースが別プロジェクトに存在していても無視します)
  • New type...
    クラスを入れるプロジェクトなどを細かく指定できます。

前者は、 ひとつのプロジェクト内に製品コードとテストコードを収めている場合には、 すばやくクラスを生成できて便利でしょう。
製品コードとテストコードを別のプロジェクトに分けている場合は、 後者の "(Generate) new type..." を使う必要があります。

それでは、 "(Generate) new type..." を選んでみます。
20100106_generatefromusage06
するとこの図のようなダイアログが出てきます。
まず先に 「場所」 (プロジェクトとファイル名) を指定してから、 上の 「アクセス」 (public, internal, ...) と 「種類」 (class, struct, interface, ...) を変更するようにします。 そして、 [OK] ボタンをクリックすれば、 Foo クラスのスケルトンが生成されます。
このとき、 フォーカスは移動しません。 今まで編集していた FooTest.cs ファイルが表示されたままですので、 テストコードの記述を邪魔されずに続けられます。

生成されたクラス ファイル Foo.cs を開いてみると、 こんなふうになっています。
20100106_generatefromusage07

 

◆ STEP-4: メソッドの生成を試してみる

続いて、 Foo クラスの Bar() メソッドのテストを書いていきます。 Bar() メソッドは、 文字列を引数に取り、 文字列を返してくれるものだとします。

ConsoleApplication1.Foo foo = new ConsoleApplication1.Foo();
string result = foo.Bar("TEST");

いきなり Assert 文の中で Bar() への呼び出しを書かずに、 上に示したようにいったん変数に受けるようにします。

Foo に Bar() は無いということで、 Bar の下に赤い波線が表示されますので、 そこにマウスカーソルを持っていくと…
20100106_generatefromusage08
「メソッド スタブを生成するオプション」 というスマートタグが現れます。
このスマートタグをクリックしてみると…
20100106_generatefromusage09
「'ConsoleApplication1.Foo' 内の 'Bar' のメソッド スタブを生成します。」 という項目が提示されます。

あるいはこれもクラスと同様に、 "Bar" にカレットを置いて右クリックしても出すことができます。
コンテキストメニューの [生成] を選べば…
20100106_generatefromusage10
「メソッド スタブ」 というメニューが出てきます。

どちらでも、 提示された項目をクリックすれば、 Bar() メソッドのスタブが生成されます。 このときも、 画面は変わりません。 続けてテストコードを打っていけます。

ConsoleApplication1.Foo foo = new ConsoleApplication1.Foo();
string result = foo.Bar("TEST");
Assert.AreEqual<string>("OK", result);

テストケースが出来上がったので、 TestMethod1 の中のどこかを右クリックして…
20100106_generatefromusage11
コンテキストメニューから 「テストの実行」 を選んでユニット テストを走らせてみます。

Bar() メソッドの中身は何も作っていませんから、 テストは失敗してくれるはずです。
20100106_generatefromusage12
実際に、 NotImplementedException 例外が出て失敗しました。

自動生成された Bar() メソッドを見てみると…
20100106_generatefromusage13
たしかに、 NotImplementedException を投げるだけのコードになっています。
※ Bar() メソッドの戻り値が、 ちゃんと string 型になっていることに注目。 Assert 文の中で Bar() への呼び出しを書いてしまうと、 戻り値の型を推測できず (Assert.AreEqual<string> と書いてるんだから、 string を返すに決まってるじゃないか、 とは思いますが。)、 object 型になってしまいます。

 

◆ STEP-5: TDD を続ける

この後は、 FooTest.cs と Foo.cs を行ったり来たりで、 TDD していくわけです。
今失敗したテストケースを通すように Foo.Bar() に製品コードを追加し、 次の失敗するはずのテストケースを FooTests に作り、 またそれを通すだけのコードを Foo.Bar() に追加し… ひととおり出来上がったらリファクタリングし、 と。

|

« [イベント] 告知 - Tech Fielders セミナー 東京 [Agile Day 「A Start - アジャイル開発が気になるあなたに贈るセッション&ワークショップ] ( 1/22, 新宿 ) | トップページ | [記事紹介] ZDNet Japan ~ ソフトウェアの新たな開発手法、「アジャイル開発」って? »

*コラム」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: [コラム] [VS2010] 新機能 Generate From Usage (使用法から生成) の使い方 Step by Step:

» [記事紹介] Visual Studio のインテリセンスって、テストファースト中には邪魔だよね [TDD.NET]
テストケースを書いているときに、 これから作る (まだ存在しない) クラスやメソッドの名前を入力すると、 Visual Studio のインテリセンスが「邪魔」をしてくれて、 イラつくこと甚だしいのですが…。 長沢智治のライフサイクルブログ: Visual Studio 2010 言語別ショートカット一覧とテスト駆動開... [続きを読む]

受信: 2011年11月 3日 (木) 18時57分

« [イベント] 告知 - Tech Fielders セミナー 東京 [Agile Day 「A Start - アジャイル開発が気になるあなたに贈るセッション&ワークショップ] ( 1/22, 新宿 ) | トップページ | [記事紹介] ZDNet Japan ~ ソフトウェアの新たな開発手法、「アジャイル開発」って? »