NUnit を使ってみる

2011年2月6日 1 開発 , , , , , ,

恥ずかしながらユニット テストをまともに使ったことがない。

重要性は理解しているつもりで、興味もあったのだけど、仕事で触れず、趣味の開発にも取り入れることはなかった。しかし、プログラマが知るべき 97 のことのテストに関するトピックを読んで、関心度がモリモリ上昇。何かをはじめる時は、こういう気分に乗るのがよい。

それと仕事でユニット テストの採用を提案するとして、自分で使っていないものを勧められようはずもない。使うにしても簡単なスニペットを書いて、それをテストして…ではダメだ。ユニット テストを考慮していないものに取り入れるほうが現実的だろう。

というわけで、 まずは趣味のプロジェクトにユニット テストを導入してみる。プロジェクトは .NET 製なので、ツールには NUnit を選ぶ。

もくじ

レガシーコード改善ガイド

いきなりユニット テストを取り入れても、その背景にある理念を知らないと、ちょっとした問題でもつまづくだろう。そして「テストなんてはじめからなかった」などと諦めてしまいそうだ。

だいいち、テストをするといっても、どんな範囲でどのように、というのがよく分からない。何かリファレンス的なものが必要だぞ、ということで、多くの人が読んでいると思われる、レガシーコード改善ガイドを購入してみた。

まだ半分ぐらいしか読んでいないが、内容は具体的かつ実践的。とても分かりやすい。

表紙に「テストがないコードはレガシーコードだ!」なんて書いてあるけど、テスト導入が難しいことを前提としており、大半の内容は、そうした状況への対策となっている。

テストは対象の依存が少ないほど実行しやすくなる。よって対策は依存性の排除や抽象化へ向かう。例を見ると過剰に感じられるが、それも織り込み済み。全体的な複雑度の増加よりも個々の機能が独立することを目指すという。このあたりは著者も誤解の元と予想したのだろう、かなり丁寧に解説している。

実現方法としてはインターフェース、PImpl イディオムや Strategy パターンといった手法が多用される。これらの実践的なサンプルとしても有用だと思う。

難点としては「詳しくは~章を参照してください」という記述が挙げられる。紙の書籍でこれはつらい。

PC であればタブやマルチウィンドウに期待できるけれど、紙媒体ならば後述は禁物だと思う。あっても、せめて数ページの範囲に留めるべきだ。その章で完結できないなら、半端に触れないほうがいい。

あと表紙のデザインが残念。素っ気ないというか、書店で面置にしても確実に埋もれるタイプ。地味すぎて、あらかじめ評判を知っている人か手に取らないだろう。オライリーならどんな生物を持ってきただろうか?などと考えてしまった。

NUnit のインストール

テスティング フレームワークの世界では xUnit 系がメジャーのようだ。Smalltalk の SUnit を元に JUnit が生み出され、様々な言語に移植されているとのこと。今回、利用する NUnit もそのひとつ。これは .NET 用のツールとなる。

まず、ダウンロード ページからインストーラーを入手する。現時点の最新版は 2.5.9。複数のファイルが公開されているけれど、これらの内、拡張子が .msi のものをダウンロードする。

入手したものは Windows インストーラ形式なので、そのまま実行すればセットアップが開始される。特に迷うことなくインストールできるだろう。

テスト プロジェクトの作成

NUnit を使用するには、テスト用プロジェクトを作成する必要がある。このプロジェクトの概要は以下のようになる。

  • nunit.framework.dll を参照している
  • テスト用メソッドを公開 ( アクセス指定子が public ) している
  • プロジェクト形式は EXE と DLL のどちらでもよい

プロジェクトは専用のものを作成する。

Conditional 属性を利用して、デバッグ版だけテスト メソッドを有効にすれば、リリース用プロジェクトにテストを書くのもありに思える。しかしnunit.framework.dll 依存が気になるし、internal までなら設定だけで外部プロジェクトから参照できる ( リフレクションを使えば private もいける )。

また、テストだけで固まっていたほうが管理しやすい。プロジェクトの参照を見ればテスト対象が一望できるし、何がテストされているかも集約されている。NUnit の設定ファイルやテスト データの置き場所も、専用プロジェクトにまとめるのがよいだろう。

以上を踏まえつつ、テスト用プロジェクトを作成してみる。

まず、Visual Studio でテスト対象を含むソリューションを開き、プロジェクトを追加する。

名前を「テスト対象 + Tests」にして、出力の種類はクラス ライブラリを選ぶ。複数のプロジェクトに対するテストを集約するなら「ソリューション名 + Tests」にすると分かりやすい。

NUnit 自身のテスト用モジュールも、このようになっている。名前からテスト対象が分かったほうがよいし、単独で実行することはないから DLL でよい、ということなのだろう。今回作成するものは、Owl というライブラリに対するテストなので、OwlTests という名前にした。

プロジェクトを作成したら、nunit.framework.dll への参照を追加する。NUnit をインストールしているなら、.NET アセンブリがシステムに登録されているはず。

次に、テストしたいプロジェクトの参照を追加する。同じソリューション内なら、プロジェクトをそのまま参照すればよい。

テスト プロジェクトから対象の internal 部分にアクセスしたい場合は、特別な設定が必要になる。テスト対象を Owl、テスト プロジェクトが OwlTests とした場合、Owl の Assemblyinfo.cs へ以下の記述を加える。

[assembly: InternalsVisibleTo( "OwlTests" )]

これで Owl の internal 部分が OwlTests に公開される。いわゆるフレンド アセンブリである。この状態でビルドすると、生成された DLL が NUnit から利用できる形式になる。

テスト コード

まず、テスト用クラスを作成する。

名前空間は「テスト プロジェクト名.テスト対象クラスの名前空間」にしておくと分類しやすい。クラス名は「テスト対象のクラス名 + Test」にする。

NUnit とテスト対象を using で参照し、テスト クラスであることを示すために TestFixture 属性を付ける。クラスとテスト メソッドのアクセス指定子は NUnit に公開する必要があるのでpublic にする。

Owl.Id3 にある MpegAudioFrameHeader というクラスをテストする場合、以下のような実装になるだろう。

using System;
using NUnit.Framework;
using Owl.Id3;

namespace OwlTests.Id3
{
    /// <summary>
    /// MpegAudioFrameHeader のテストを実行します。
    /// </summary>
    [TestFixture]
    public class MpegAudioFrameHeaderTest
    {
    }
}

NUnit は多機能で、テスト コードの表現力も非常に高い。けれどはじめは Test、TestCase 属性と Assert クラスのメソッドをいくつか知っておけばよいと思う。

Test または TestCase 属性を付けたメソッドがテスト対象になる。メソッドを単体実行するなら Test、ひとつのメソッドで複数条件をテストしたいなら TestCase を利用する。

テスト メソッド内では、Assert クラスのメソッドを実行する。メソッドが実行されたとき、正常ならテスト成功、Assert が起きるなら失敗となる。例えば Assert.AreEqual() なら期待値と値が異なることをチェックし、Assert.Throws()、Assert.That() を組み合わせると例外の発生をテストできる。

一般的な NUnit の入門記事だと、Test 属性 + Assert.AreEqual() を説明することが多いけど、TestCase 属性がそれを兼ねられるので、利用機会は少ない。よってはじめは TestCase 属性を使ってみる。実際に書いてみると、以下のようになる。

/// <summary>
/// バージョン情報の読み込みをテストします。
/// </summary>
/// <param name="version">MPEG バージョンとレイヤー。</param>
/// <param name="target">バージョン情報の期待値。</param>
[TestCase( 0xFB, "1",   TestName = "MPEG 1"   )]
[TestCase( 0xF3, "2",   TestName = "MPEG 2"   )]
[TestCase( 0xE3, "2.5", TestName = "MPEG 2.5" )]
public void ReadMpegVersion( byte version, string target )
{
    var expected = MpegVersion.None;
    switch( target )
    {
    case "1":   expected = MpegVersion.Mpeg1;   break;
    case "2":   expected = MpegVersion.Mpeg2;   break;
    case "2.5": expected = MpegVersion.Mpeg2_5; break;
    }

    var h = new MpegAudioFrameHeader( new byte[ 4 ] { 0xFF, version, 0x00, 0x00 } );
    Assert.AreEqual( expected, h.Version, "バージョン" );
}

TestCase 属性のパラメーターは可変長で対象となるメソッドの引数に対応している。また、属性は複数同時に定義できる。この仕組みを利用することで、単一メソッドによる複数条件テストを書ける。

条件ごとに名前を付けたいなら、TestName パラメーターを指定する。ここに書いた名前は NUnit 上にそのまま表示される。テスト用パラメータと区別するために、記述する位置は末尾にするとよいだろう。

あと、この例では引数をわざわざ文字列にして、メソッド内で MpegVersion 列挙体に変換しているのだが、これには理由がある。MpegVersion 列挙体は Owl.dll で internal として定義されているため、OwlTests.dll の public メソッドの引数に指定できない。

internal もテスト可能といっても、アクセス指定の仕組みは通常どおりになる。案外、はまりそうなので、あえて例に挙げてみた。

Assert.AreEqual() は、第一引数に期待値、第二へ評価する値、第三を Assert が発生した時のメッセージにする。第一、第二引数の内容が一致するならテスト成功、それ以外は Assert になる。

次は例外についてのテストを書いてみる。

/// <summary>
/// 同期ヘッダが見つからなかった時の振る舞いをテストします。
/// </summary>
[Test]
public void FailSyncHeader()
{
    var ex = Assert.Throws< ArgumentException >(
       () =>
       {
           var header = new MpegAudioFrameHeader( new byte[ 4 ] { 0x00, 0x00, 0x00, 0x00 } );
       } );

    Assert.That( ex.Message == "'Sync header' has no information.", "同期ヘッダ" );
}

Assert.Throws の型パラメーターに例外クラスを指定することで、引数のメソッド内で発生した例外を補足してくれる。その内容が戻り値となるので、それを Assert.That() で評価することで、例外をチェックできる。

try – catch 方式でテストする場合は try で例外の有無、catch で例外の内容を評価する必要があるけれど、この方法なら評価部分が Assert.That() だけで済む。指定された例外が発生しなかったなら Assert.Throws() の戻り値は null になるのでテストも失敗してくれる。

NUnit でテストを実行してみる

NUnit を起動して以下の手順を実行する。

  • NUnit のメイン メニューから「File」→「New Project…」を選ぶ
  • ファイル保存ダイアログが表示される
  • テスト プロジェクトのフォルダを開く
  • テストプロジェクト名.nunit という名前でファイルを保存し、ダイアログを閉じる
  • NUnit のメイン メニューから「Project」→「Add Assembly…」を選ぶ
  • ファイル選択ダイアログが表示される
  • テスト プロジェクトの bin\Debug または Release を開く
  • テスト プロジェクトの DLL を選んでダイアログを閉じる

すると NUnit の左にあるツリーに、テスト メソッドが表示される。

NUnit

これらのどれかを選んだ状態で、NUnit の右にある Run ボタンを押すとテストが実行される。テストに成功したら緑、失敗なら赤が表示される。

テストを実行

赤になった時は原因も表示されるため解決の参考になる。Assert.AreEqual() によるチェックなら期待値と実際の値、Assert に到達できず例外が発生した場合はその内容が出力される。

Visual NUnit

NUnit は対象プロジェクトがビルドされると自動的にモジュールを読み直してくれる。しかしたまに失敗する。その場合は Socket が云々というエラーが表示され再起動するまで操作を受け付けなくなったりする。

Visual Studio で開発している場合、テスト実行のために NUnit へ移るのは面倒である。Visual Studio Professional の標準テスト機能なら内部実行できるので NUnit でも同じことができればなぁと思って調べたところ Visual Nunit というツールを見つけた。

これは前に紹介した AnkhSVN と同じく拡張機能となるので、インストールすると Visual Studio に統合される。セットアップの手順は以下。

まず Visual Studio のメインメニューから「ツール」→「拡張機能マネージャー」→「オンラインギャラリー」を選ぶ。次に右上の検索欄に NUnit と入力して Visual NUnit を探す。

拡張機能マネージャー

Visual NUnit が見つかったら「ダウンロード」ボタンを押す。すると以下の確認メッセージが表示されるので「インストール」ボタンを押す。

インストール確認

インストールが完了すると拡張機能マネージャーの下部に「変更を有効にするには Microsoft Visual Studio を再起動する必要があります。」と表示されるので「今すぐ再起動」ボタンを押す。自分で再起動してもよい。

再起動メッセージ

再起動した後に NUnit を利用しているソリューションを開き、メインメニューから「表示」→「その他のウィンドウ」→「Visual NUnit」を選ぶ。

Visual NUnit の表示

すると Visual NUnit のウィンドウが表示される。自動的にテスト コードが読み取られ以下のようにリスト アップされる。

Visual NUnit

ウィンドウ内の「→」と書かれたボタンを押すとテストを実行してくれる。この記事を書いている最中に更新があり、最新版だと「→」ボタンは「Run」という表記になったようだ。

Visual NUnit でテスト実行

個別にテストを実行する場合はリストから単体を選択する。複数なら Ctrl や Shift キーを押しながら項目を選ぶ。Ctrl + A で全選択になる。

このツールを使うとテストから実行までを Visual Studio で完結できて非常に便利。惜しむらくは、GUI がリストなので NUnit のように階層選択できないことか。

Xperia でキーボードを使う

2011年1月16日 2 ガジェット , , , ,

TK-FBP017BK + BlueKeyboard の組み合わせが思いの外、快適だったので紹介してみる。

小さなメモ用端末が欲しくて、ポメラの新製品が発表される度に購入を迷っていたのだけど、スマートフォンと 2 台持ちになるのはイマイチだなぁと思い、躊躇していた。

Xperia + キーボードでポメラ的な使い方ができるのが理想。なので、TK-FBP017BK が発売された時は小躍りしたものだ。

しかし発売当時の Xperia は Android 1.6 で、その場合、SPP というモードで接続することになるのだが、この方法はレスポンスが非常に遅いらしく、評判をググってみるとすこぶる悪い。また、製品の標準価格が 20,790 円と高額 ( この記事を執筆している時点では値引きされ、1 万円をきっている ) なことも相まって、Xperia でキーボードは無理なんだな、と諦めてた。

ところが最近、偶然にも TK-FBP017BK を触る機会に恵まれた。

はじめは製品の説明書にあるとおり SPP モードを試し、噂通りの遅さに辟易とする。キー入力からの応答に 1 秒ぐらい待たされるし、Back Space を押しっぱなしにしても連続入力にならず、テキストの削除が非常に面倒である。

どうやらこれはアンテナの感度による問題らしく、改造によってレスポンスを向上させている方もいるようだ。

しかし Web でこの製品についてググってみると、Android 2.1 以上で BlueKeyboard というアプリを利用するなら快適だ、という意見も散見される。

実際、このアプリを利用してみたところ実用的なレベルのレスポンスが得られた。これならいける。すばらしい!!

な、記事のタイトルに Xperia と書いているが Nexus S でも動作することを確認した。Android 2.1 以降ならどのメーカーの端末でも大丈夫だと思う。

というわけで以降に TK-FBP017BK と BlueKeyboard の利用方法を紹介してみる。

TK-FBP017BK

まずは TK-FBP017BK を購入する。

発売当初は高額だったが、現在はずいぶんと値引きされているようだ。人気が出たら値上がりするかもしれないけれど。

TK-FBP017BK の設定は非常に簡単。キーボードを開き、同梱されている電池 ( 単 4 x 2 本 ) をセットするだけで使い始められる。右上に SPP – OFF – HID の 3 モードを切り替えるスイッチがあり、接続する際は SPP か HID にしておく。動作中はスイッチの近くにある LED ランプ ( 緑色 ) が点灯する。

電池が満タンの状態から使用した場合、およそ 3 ヶ月は持つとのこと。とはいえ、Bluetooth は消費電力は大きいので、使用しないときは OFF にしたほうがよいだろう。

ちなみに私は Amazon で購入したのだが、初期不良により交換となった。

電池を入れても LED ランプが点灯しない。SPP、HID に切り替えてもダメ。当然、Xperia や PC からも認識されない。エレコムのサポートに問い合わせたところ、やはり不良とのこと。

Amazon で返品・交換を手続きするのは初めてだったが、Web フォームで手続きしたら、すぐに代わりの品が発送された。昨日の夜に申し込み、今日の午前に届いた。何とスピーディーな対応なのだろう。すばらしい。

なお、故障していた製品は 1 ヶ月以内に Amazon 側へ送る必要がある。どうやら集荷サービスもあるらしい。

BlueKeyboard の入手とインストール

アプリの入手は Android Market から行う。BlueKeyboard で検索すれば、すぐに見つかるはず。

Android Market から探す

BlueKeyboard は無償・有償版がある。無償版は使用している間、画面下部へ広告が入る。またユーザー辞書の編集が無効になっている。有償版はこれらの制約がない。ちなみに価格は 2011 年 1 月 16 日の時点で 105 円。

BlueKeyboard JP

無償版でも十分に実用的だが、文字入力する場面で広告が入るのがイマイチなのと便利なアプリを開発してくれた作者に感謝したいという気持ちから有償版を購入してみた。

設定の手順は無償・有償のどちらも一緒なので、はじめは無償版を試すのがよいだろう。インストールについても通常のアプリと同様に Android Market から行えるので迷うことはないはず。

TK-FBP017BK を認識させる

まず TK-FBP017BK の右上にあるスイッチを HID に切り替え、ランプが点灯することを確認する。

次に Xperia 上のホーム画面などでメニューボタンを押し、設定画面へ移動する。そして「無線とネットワーク」→「Bluetooth 設定」を選ぶ。

Bluetooth 設定

この画面で Bluetooth を有効にして「検出可能」のチェックを入れた後に「端末のスキャン」を押す。近辺の Bluetooth 機器検索が開始されるので TK-FBP017BK 左上にある Blutooth ボタンを押す。しばらくするとELECOM TK-FBP017 という項目が表示される部分を押す。

するとペア設定リクエストのメッセージ ボックスが表示される。メッセージに 6 桁の番号が書かれているので覚える。

ペア設定

OK ボタンを押してメッセージ ボックスを閉じたら、キーボードの上部にある数字のキーから覚えた番号を入力して最後に Enter キーを押す。入力に失敗するとエラーが表示されるが何度でも挑戦できるので焦らずに試す。

ペア設定のエラー

成功すると、機器名の下に「ペア設定 非接続」と表示される。

ペア設定に成功した状態

なんだか失敗しているように見えるが実際の接続は BlueKeyboard で行うので問題ない

BlueKeyboard の設定

Xperia 上のホーム画面などでメニューボタンを押し、設定画面へ移動する。そして「言語とキーボード」を選ぶ。
選択できる形式として BlueKeyboard JP が追加されている。

言語とキーボードの設定

BlueKeyboard JP を有効にしてから設定を開く。「使用するキーボード」という項目があるので押すとキーボード選択のダイアログが表示される。TK-FBP017BK が認識されていれば ELECOM TK-FBP017 が表示されているはず。これを選択してダイアログを閉じる。

キーボード選択

次は「キー配列」という項目を押してキー配列選択のダイアログを表示する。配列の候補から ELECOM TK-FBP017 を選びダイアログを閉じる。

キー配列

これで準備完了。では早速、キーボード入力を堪能してみよう。

テキストボックスを持つアプリなら何でもよいので起動する。そしてテキストボックス部分を長押しして入力方法の選択ダイアログを表示。候補から BlueKeyboard JP を選ぶ。

文字入力の方法を変更

すると、BlueKeyboard が TK-FBP017BK との接続を開始する。

うまく認識できないときは TK-FBP017BK と Xperia の距離を近づけたり TK-FBP017BK 左上の Bluetooth ボタンを押してから接続を試みる。

成功すると接続できたことを示すメッセージが表示されキー入力が Xperia 上のテキストボックスに送信されるようになる。

キーボードから入力してみる

キー入力に対するレスポンス速度はけっこう早い。PC ほどではないが十分に実用的だ。
Evernote や Gmail、twicca のような Twitter クライアントなどのように文字入力する機会の多いアプリはかなり快適になる。

あと ConnectBot という SS クライアントでも BlueKeyboard + TK-FBP017BK を使用できる。このブログを設置しているサーバーへの接続にも成功した。

コマンドをフリックで入れるのは大変すぎるがキーボードなら快適なので、出先でサーバーを操作したいときに役立ちそうだ。

ハードウェア的な感想

折りたたみ式なのでキータッチについては期待していなかったのだけど、廉価なノート PC ぐらいの品質はあると思う。キー配置も癖がなく、取っつきやすい。方向キーとスペース キーが大きめなのも気に入った。

膝上で利用するには厳しい。広げた状態でロックできるけれど打鍵でたわむ。机上で使用することを前提としたほうがよいだろう。キーボード、スマートフォンともに省スペースなので、置く場所に困ることはないだろう。電車で利用するなら、ビジネスバッグの上に置くのが現実的か。

スマートフォンを置くためのスタンドは本体左上に格納されている。使うときは引き出す。作りが脆いので取り扱いには注意が必要。一見、キーボード本体に固定されているようだが、最後まで引き出せば独立していることがわかる。引き出して、キーボードの中央に置くのが使いやすい。

スタンドの下部は抜きが設けられている。Xperia でストラップを利用している場合は、ここを通すとよい。

Android はハードウェア的なレイアウトが統一されていないので、機種によってはスタンドに干渉するかもしれない。

例えば Nexus S は縦にしたとき、下部に USB 端子がくるので、スタンドに乗せるのは厳しく、USB 接続したまま利用するなら横向きの方がよいだろう。

ところで PC 的な機能はスマートフォン、入力デバイスとしてキーボードを手に入れたわけだが、これにプロジェクタが加われば鬼に金棒だと思う。Xpeia arc のように HDMI 出力をサポートしてくれれば液晶テレビでもよい。

キーボードは Bluetooth で無線化されているわけだから出力装置の側にスマートフォンを置き、手元の TK-FBP017BK でプレゼンを進行させたりする。議事録ドリブンで会議をおこなっているなら議事録を巨大なスクリーンに投影しつつ編集するのもよいだろう。

次にスマートフォンを買い換えるときは外部ディスプレイ出力をサポートしている端末を選び、そんな使い方をしてみたいものだ。

AnkhSVN

2010年10月2日 1 ソフト紹介 , , , ,

Visual Studio 用の Subversion 連携プラグイン、AnkhSVN についての覚え書き。

Redmine と Subversion をさくらのVPS 上で稼働させて TortoiseSVN から操作していたのだけど、Eclipse のように Visual Studio からリポジトリ操作をおこないたくなったので AnkhSVN というプラグインを導入してみた。

まず Visual Studio だが、Express Edition ではプラグインが利用できないので上位エディションにしなければならない。Eclipse に比べるとちょっとなあ、と思いつつ Professional アップグレード版を購入。

  • 追記 2010/10/04
    • 表現が正確ではないので訂正
    • Visual Studio 2010 Express Edition でも拡張マネージャーを利用できる
    • ただし一部のプラグインを入れられない
    • AnkhSVN もその一つらしく、Express Edition では拡張マネージャーにリストアップされないようだ
    • はじめはサードパーティ製プラグイン全般がダメだと思っていたのだが、作者が個人名になっているものもあり、基準がよくわからない

~~Amazon の商品紹介を貼ってみたが、現時点ではカスタマーレビューが 1 件もない。発売から半年ぐらい経っているのだが、そんなに人気ないのだろうか?~~←この記事を書いた後にレビューが追加されていたようだ。ちょうど拡張マネージャに関する訂正があったので、前の表記を残しつつこちらも訂正。

Visual Studio 2010 には拡張マネージャーという機能が付いていて、プラグインのリストアップやインストールがおこなえる。メインメニューから「ツール」→「拡張マネージャー」を選択して起動する。

拡張機能マネージャー

AnkhSVN はオンラインギャラリーに公開されているのでリスト中からこれを選び、ダウンロードボタンを押す。すると公式サイトに飛ばされるのでインストーラをダウンロードする。

インストーラのダウンロード

また Eclipse との比較になってしまうのだけど、拡張機能マネージャからダイレクトに「ダウンロード」→「インストール」をおこなえないものだろうか。ClickOnce のような優れた仕組みを実現できているのだから、将来のバージョンでは改善してほしい。

AnkhSVN をインストールした後に Visual Studio を起動すると、ソリューション エクスプローラが拡張される。ツリーのアイコンに変更状態をあらわすグラフィックが表示され、コンテキストメニューにはリポジトリ操作用の項目が追加される。

予めリポジトリに登録済みのソリューションをチェックアウトした場合、Visual Studio で開くと AnkhSVN が Subversion の情報を読み取ってくれる。リポジトリ未登録のソリューションは AnkhSVN 経由で Visual Studio 上からも登録できる。

ソリューション エクスプローラ

チェック印の付いているものが Subversion のリポジトリと一致しているもので、赤い四角が編集によって差分の発生したファイルとなる。Eclipse のようにリビジョンも表示してくれるとありがたいのだけど、それは将来に期待するとしよう。

編集したファイルとリポジトリの差分を確認するビューアーも用意されている。ソリューション エクスプローラ上から編集されたファイルを選択し、コンテキストメニューから Show Changes を選ぶと、以下のように差分が表示される。

リポジトリとローカルの差分チェック

赤が削除、緑が差分、青が挿入のあった行となる。もし差分が好ましくなければ、コンテキストメニューから Revert を選ぶことで編集を取り消せる。尚、Subversion 的な仕様なのだが、チェックアウトや Revert などをおこなうと、ファイルの更新日時は最新になるので、これを変更の目安にする場合は注意が必要である。

編集内容が適切であることが確認できたら、コンテキストメニューから Commit… を選んでコミット ダイアログを表示する。複数のファイルをまとめてコミットしたい場合は、それらをまとめて選択してから同じ操作をおこなう。

Visual Studio のソリューション エクスプローラはツリービューに見えるが複数選択にも対応している。何かアイテムをクリックして、Shift キーを押しながら別のものをクリックすればその範囲が選択される。個別に選択する場合は Ctrl キーを押しながらアイテムをクリックしてゆく。

コミット ダイアログは以下のようになっている。

コミット ダイアログ

Log Message と書かれている欄はコミット時のコメントで、このテキストボックス左下に見える 100% と書かれている部分をクリックするとコメントの文字サイズを拡大・縮小できる。左下の Keep Locks をチェックすると、コミット後もロック状態が維持される。Keep Changelists はチェンジリスト ( セット ) に関する設定のようだが、使い道がわからない。

RedmineTrac を利用しているならば、コメントに refs、closes、fixes といった語句と共にチケット番号を記述することで、コミットとチケットを関連付けられる。書式は refs #N となる ( N の部分にチケット番号を記述 )。

例えば Redmine のプロジェクトと Subversion のリポジトリが関連付いている状態で、refs #9 と書いてコミットすると、プロジェクト内の #9 のチケットに反映される。

Redmine 上の表示

Redmine のリポジトリ画面を開くと、さきほどのコミットはリビジョン番号 11 となり、コメントがそのまま出力されていることが分かる。#9 となっている部分はチケットへのリンクになっており、これをクリックするとチケットのページへ移動できる。

TortoiseSVN でも同様の操作がおこなえるが、Visual Studio から画面を切り替えずに実現できるのは非常に快適。また、複数ファイルを同時にコミットする操作も、ソリューション エクスプローラの方が必要最小限のファイルしか表示されないのでわかりやすい。つかい始めると手放せなくなる便利プラグインだ。

ちなみに AnkhSVN の日本語化については、最新バージョンに追従できてないので取り上げなかった。AnkhSVN の公式 FAQ を見ると

I heard that AnkhSVN will be localized, what can I expect? We would like to create localized versions of AnkhSVN in all languages that Visual Studio is available in. As far as I can tell the list of languages for VS2010 contains English (en-us, neutral, fallback), French, German (de), Japanese, Spanish (es), Italian (it), Russian (ru), Traditional Chinese, Simplified Chinese and Korean. As we (the current AnkhSVN developers) don’t understand most of these languages, we would like to get in contact with users/developers that do and are willing to help us parts of AnkhSVN into these languages. If you are interested, please contact us via the user and/or development lists. We hope to deliver a first localized version in the AnkhSVN 2.2/2.3 timespan.

となっているので、将来バージョンでは TortoiseSVN のように公式な多言語対応されるかもしれない。非常に楽しみである。