ExceptionAsserts と VS での C# プロジェクトのデバッグ
-
21-09-2019 - |
質問
私たちはしばらくの間、NUnit と VisualStudio を使用して C# .NET コードを作成してきました。例外のテストは次のスタイルで行われました。
古い構文:
[Test]
[ExpectException(typeof(ExceptionType))]
public void TestExceptionType()
{
}
現在、NUnit はバージョン 2.5.2 をリリースしており、 Assert.Throws( Type expectedExceptionType, TestDelegate code );
これにより、例外テストがより柔軟になります。例外テストは次のようになります。
新しい構文:
[Test]
public void TestWithNullBufferArgument()
{
ArgumentNullException ex = Assert.Throws<ArgumentNullException>(() => _testInstance.TestFunction(null));
// now you can examine the exception and it's properties
Assert.AreEqual(ex.Message, "Argument was null");
}
私たちの問題は、Assert.Throws が使用されている場合、プログラムのデバッグに NUnit (コンソールまたは GUI ランナー) が使用されているときに、Visual Studio が未処理の例外を示すウィンドウを表示することです。
これを明確にするために: デバッグ時に nunit-x86.exe を実行するように単体テストを含む VS プロジェクトを設定しました。(プロジェクトのプロパティ、[デバッグ] タブを参照してください。開始アクションは nunit-x86.exe を実行するように設定されています)
これにより、NUnit はテストを続行できなくなります。F5 キーを押してデバッグ/単体テストを続行することもできますが、これは実行可能な解決策ではありません。
これを回避する方法はありますか?Assert.Throws の周囲に try...catch ブロックを配置しても、デリゲート コードで例外が発生するため、何も起こりません。
誰かがこれに光を当ててくれることを願っています。
解決
この問題自体は、[マイ コードのみを有効にする] オプションがオンになっている可能性が高くなります ([ツール] -> [オプション] -> [デバッグ] -> [全般] -> [マイ コードのみを有効にする])。
「この機能が有効になっている場合、デバッガはユーザー コード (「マイ コード」) のみを表示してステップインし、システム コードや、最適化されているコードやデバッグ シンボルを持たないその他のコードは無視します。(「」を参照)「一般」、「デバッグ」、「オプション」ダイアログ・ボックス")
通常、リリース バージョンの nunit.framework.dll には、対応する nunit.framework.pdb ファイルがありません。
したがって、2 つのオプションがあります。
「マイコードのみ」機能を無効にする
nunit のソースをダウンロードします (から http://www.nunit.org/index.php?p=download)、デバッグ モードでビルドし、すべての nunit.framework.* (dll、pdb、xml) をソリューション内の lib または他のディレクトリに配置し、テスト プロジェクトでその nunit.framework.dll を参照します。
お役に立てれば。
他のヒント
同じ問題がかなり長い間私を悩ませていました。いくつかのテストを行ったところ、次のことがわかりました。
ライブラリ (この場合は nunit) がデバッグ情報を「なし」に設定してコンパイルされている場合、以下のような構成がライブラリ内で実行され、デリゲートのコードが例外をスローすると、VS はユーザーによって処理されない例外について文句を言わなくなります。コード。
ライブラリコード:
public static Exception Throws(TestDelegate code, string message)
{
Exception caughtException = null;
try
{
code();
}
catch (Exception ex)
{
caughtException = ex;
}
return caughtException;
}
クライアントコード:
private void btnTest_Click(object sender, EventArgs e)
{
var ex = MyAssert.Throws(() => { throw new Exception(); }, "");
}
ライブラリ プロジェクトのデバッグ情報を「なし」以外のオプションに設定すると、問題が解決します。デバッガは、こうした「未処理」の例外が発生しても停止しなくなりました。私は、nunit と、上記のコード (nunit の Throws メソッドから抜粋した) を使用した独自のハンドロール ライブラリを使用してテストしました。それがVSの特徴というか「特徴」なのでしょう。
選択肢はそれほど多くありません。
前に提案したように例外をフィルターします
煩わしい停止を避けるために、ローカルで使用するために nunit.framework.dll を再コンパイルします。
他のオプションとしては、MS チームまたは NUnit チーム、またはその両方に連絡して、問題を調査/明確にし、最小限のデバッグ情報を使用して NUnit をコンパイルするよう依頼することもできます。
編集:
もう一つ選択肢が見つかりました。
- 私の場合、ライブラリがデバッグ情報なしでコンパイルされている場合でも、「モジュールロード時に JIT 最適化を抑制する」のチェックを外すとうまくいきます。ただし、プロジェクトがリリース構成で実行されている場合にのみ機能します。
私はNUnitのアサーションによって盲目にされていると思います。あなたは、単純なのtry / catchで同じことを実現することができます。
try
{
_testInstance.TestFunction(null);
Assert.Fail("The method should have thrown...");
}catch{}
さて、あなたはあなたが必要なすべてを持っています。例外がスローされていない場合は失敗し、期待どおり通常のコードは、例外を処理することができます。
それは例外を無効にすることによって達成できるだろう。 オープンデバッグ/例外メニュー、そしてあなたの例外を検索します。