OITA: Oika's Information Technological Activities

@oika 情報技術的活動日誌。

NUnit 例外テストの評価をデバッガ上で実行できない問題

NUnitを使ってテストを書くときに
テストコードのプロジェクトをコンソールアプリとかにしておいて
Mainメソッドの中でGUI Runnerを呼び出すようにすれば
いちいちNUnitを別で立ち上げずにexeからテストを開始できたり、
VisualStudio上でデバッガ実行できたりして便利になる。

一応例を書いておくと以下のような感じ。

HogeAppというプロダクトのテストプロジェクトを
HogeAppTestsという名前のコンソールアプリとして作ったら、
参照の追加で以下3つを入れる。
・nunit.framework
・nunit.gui-runner
・System.Windows.Forms
(Windows.FormsはApplication.ExecutablePathを使うためだけに使用)

あとはProgram.csのメインを以下のように。

[STAThread]  
static void Main(string[] args) {  
    var prms = new[] { Application.ExecutablePath, "/run" };  
    NUnit.Gui.AppEntry.Main(prms);  
}  

ここからが本題。

NUnitで例外が投げられるかどうかを確認するようなテスト
(ExpectedException属性なり、Assert.ThatでのThrows.Exceptionなり)
を書いたとき、
VisualStudioのデバッガからテストを実行すると、
プロダクトコード側で例外が投げられた時点でデバッガが止まってしまい、
テストが通らなくなってしまって困ったという話。

構成としては、1つのソリューションの中で
プロダクトのプロジェクトとテストプロジェクトが分かれている状態。

で、どうやらVisualStudioのデバッガオプションで
「マイコードのみ」を有効にしている場合だけ
プロダクトコード側でデバッガが止まってしまうようだった。

なので、「マイコードのみ」設定のチェックを外せば一応は解決。
でもなんとなく直感と違う動きのような気もするが…。

マイコードのみ設定についてはmsdnに説明があるけど
いまいちちゃんと理解できていないのよな…。
方法: マイ コードのみにステップ インする

あるいは、もちろん以下のようにテストを書き直す手もある。
ちょっと格好悪いけど。

修正前)

Assert.That(() => DoSomething(null),   
            Throws.TypeOf<ArgumentNullException>());  

修正後)

try {  
    DoSomething(null);  
    Assert.Fail();  
} catch (ArgumentNullException) {  
}