9

このパターンの単体テストがいくつかあります。

[TestMethod ()]
[ExpectedException (typeof (ArgumentNullException))]
public void DoStuffTest_Exception ()
{
    var foo = new Foo ();
    Foo.DoStuff (null);
}

コード カバレッジはスロー行をハーフランとしてマークすることが判明したため、毎回 1 ブロックのカバーされていないコードを取得します。

この問題についてしばらく考えた結果、私が思いついた最善の解決策は、try/catch を追加することでした。これは繰り返されるパターンなので、次のようなヘルパー メソッドを作成します。

public static void ExpectException<_T> (Action action) where _T: Exception
{
    try { action(); }
    catch (_T) { return; }
    Assert.Fail ("Expected " + _T);
}

これには、スローしないテストにすべての例外テストを追加できるという副次的なメリットがあります。

これは有効な設計ですか、それとも何か見逃していましたか?

編集: Ugs ...上記のExpectExceptionメソッドのように思えますが、カバーされていないブロックも1つ残されています。

4

4 に答える 4

10

あなたが提案していることは有効です。コードカバレッジの問題は別として、ExpectedException属性を使用するよりも優れていると主張します。これは、テストのどの行が例外をスローすると予想されるかを明示的に示しているからです。UsingExpectedExceptionは、テスト内のどのコード行でも予期される例外タイプをスローでき、テストは引き続きパスすることを意味します。スローされることが予期されていなかった別の呼び出しからエラーが発生した場合、スローされるはずの行がそうではないため、テストが失敗するはずであるという事実を偽装できます。

あなたが提案したものに対する有用な変更は、キャッチされた例外を返すことです:

public static _T ExpectException<_T> (Action action) where _T: Exception
{
    try { action(); }
    catch (_T ex) { return ex; }
    Assert.Fail ("Expected " + typeof(_T));
    return null;
}

これにより、必要に応じてテスト コードで例外をさらにアサートできます (つまり、特定のメッセージが使用されたことを確認するため)。

NUnit (ただし、属性があるため使用しているようには見えませんTestMethod) には、提案したものと同様の組み込みの構造があります。

Assert.Throws<ArgumentNullException>(() => Foo.DoStuff(null))
于 2009-10-22T11:32:51.560 に答える
2

これは古いトピックであることは知っていますが、同じ問題に遭遇しました。

結局、私は自問自答しました: なぜテストのカバレッジを知る必要があるのですか? 私はしません!- では、それらを除外して、カバレッジがよりクリーンになるようにしましょう。

私のテスト プロジェクトでは、CodeCoverage.runsettingsファイルを追加しました。これがコンテンツです。

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        <Configuration>
          <CodeCoverage>
            <ModulePaths>
              <Exclude>
                <ModulePath>.*tests.dll</ModulePath>
                <ModulePath>.*Tests.dll</ModulePath>
                <!-- Add more ModulePath nodes here. -->
              </Exclude>
            </ModulePaths>
          </CodeCoverage>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

このテスト設定ファイルを選択すると、コード カバレッジは 100% になります

このように、100% を達成するためだけに、単体テスト コード カバレッジ システムを「ハック」する必要はありません :-)

于 2015-12-08T14:12:46.373 に答える
0

うん、これはかなり標準的な運賃です - 私たちのテストの多くは同じことをします. 同時に、コード カバレッジにあまり価値を置いていないのではないかと疑問に思う必要があります。

于 2009-10-22T11:00:52.777 に答える