MSTEST0067: テスト コードで呼び出しを同期的にブロックしないようにする

財産 価値
ルール識別子 MSTEST0067
タイトル テスト コードで呼び出しを同期的にブロックしないようにする
Category Usage
修正が破壊的か非破壊的か Non-breaking
既定で有効 No
既定の重大度 情報
バージョン で導入された 4.3.0
コード修正はありますか No

この規則は、MSTest 4.3 以降で使用できます。 既定では無効になっています。 <MSTestAnalysisMode>All</MSTestAnalysisMode>が設定されている場合、警告として有効になります。

原因

テスト コードでは、 Thread.SleepTask.WaitTask.WaitAllTask.WaitAnyTask<TResult>.Resultなどの同期的にブロックする呼び出しが使用されます。

このルールは、 TestMethodAttribute でマークされたメソッド (継承するカスタム属性を含む) と、 TestInitializeAttributeTestCleanupAttributeClassInitializeAttributeClassCleanupAttributeAssemblyInitializeAttributeAssemblyCleanupAttributeGlobalTestInitializeAttribute、および GlobalTestCleanupAttributeでマークされたフィクスチャ メソッドに対して発生します。

ルールの説明

テスト メソッドまたはテスト フィクスチャ内の現在のスレッドを同期的にブロックすることは、一般的なフラキネスの原因であり、協調スケジューリングを必要とする同期コンテキストでテストをテスト フレームワークが実行すると、デッドロックが発生する可能性もあります。 時間ベースの待機には await Task.Delay を優先し、タスクを await して結果を観察します。

[TestClass]
public class TestClass
{
    [TestMethod]
    public async Task Test()
    {
        Thread.Sleep(1000); // Violation
        var result = ComputeAsync().Result; // Violation
        ComputeAsync().Wait(); // Violation
    }

    private static Task<int> ComputeAsync() => Task.FromResult(42);
}

違反を修正する方法

対応する非同期版を使用してください:

[TestClass]
public class TestClass
{
    [TestMethod]
    public async Task Test()
    {
        await Task.Delay(1000);
        var result = await ComputeAsync();
    }

    private static Task<int> ComputeAsync() => Task.FromResult(42);
}

どのようなときに警告を抑制するか

このルールはデフォルトで無効化されています。 このオプションを有効にした場合、同期待機が意図的であり、回避できない場合 (非同期化できない同期APIとやり取りする場合など) には、個々の発生を抑制します。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable MSTEST0067
// The code that's violating the rule is on this line.
#pragma warning restore MSTEST0067

ファイル、フォルダー、またはプロジェクトのルールを無効にするには、noneでその重要度をに設定します。

[*.{cs,vb}]
dotnet_diagnostic.MSTEST0067.severity = none

詳細については、「 コード分析の警告を抑制する方法」を参照してください。