MSTEST0076: 並列化されたテストでプロセス全体のカルチャを変更しないようにする

財産
ルール識別子 MSTEST0076
タイトル 並列化されたテストでプロセス全体のカルチャを変更しないようにする
Category Usage
修正が破壊的か非破壊的か Non-breaking
既定で有効 Yes
既定の重大度 情報
バージョン で導入された 4.4.0 (プレビュー)
コード修正はありますか No

Note

このアナライザーは、アセンブリの並列処理が構文的に有効になっている場合 (たとえば、一致する[assembly: DoNotParallelize]のない[assembly: Parallelize]を使用する場合や、.editorconfig ファイルがmstest_parallel_safety_mode = always設定されている場合にのみアクティブ化されます。 アナライザーは、 .runsettings または MSBuild プロパティ ( MSTestParallelizeWorkers など) でのみ有効になっている並列処理を検出できません。 このように並列化を構成し、このアナライザーを実行する場合は、 .editorconfig オプションを設定します。

原因

テストまたはクラス スコープのフィクスチャ メソッドを実行すると、一致する[ResourceLock][DoNotParallelize]なしでDefaultThreadCurrentCultureまたはDefaultThreadCurrentUICultureが割り当てられます。

ルールの説明

CultureInfo.DefaultThreadCurrentCulture DefaultThreadCurrentUICultureプロセス全体の既定のカルチャを設定するため、同時に実行されるすべてのテストで変更が観察され、書式設定や解析が破損する可能性があります。 スレッドごとのフォームとアンビエント フォーム (Thread.CurrentThread.CurrentCulture/CurrentUICultureCultureInfo.CurrentCulture/CurrentUICulture) にはフラグが設定されません。最新の.NETでは、実行コンテキストと共に流れるAsyncLocalに基づく値が割り当てられるため、兄弟テストが破損することはありません。

[TestMethod]
public void SetsCulture()
{
    CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; // Violation
}

フラグ付きセッターはプロセス全体であるため、 finally ブロック内の前の値を復元しても役に立ちません。テストを同時に実行しても、変更の期間中、変更されたカルチャが観察されます。

違反を修正する方法

テストに [DoNotParallelize] を追加するか、プロセス全体のカルチャを変更しないようにし、代わりにスレッド単位またはアンビエント カルチャプロパティを使用します。

[DoNotParallelize]
[TestMethod]
public void SetsCulture()
{
    CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
}

カルチャの既知の [ResourceLock] キーは存在しないため、宣言された任意の種類の [ResourceLock] は、カルチャ アクセスを調整したことを示す受信確認として扱われ、この規則はサイレントのままです。

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

並列化を無効にしたり、スレッドごとのカルチャ プロパティに切り替えたりせずに、この規則からの警告を抑制しないでください。これは、同時に実行されるテストに対して無言で変異が競い合う状態になるためです。

警告を抑制する

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

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

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

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

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

こちらも参照ください