MSTEST0067: Unikaj synchronicznego blokowania wywołań w kodzie testowym

Property Value
Identyfikator reguły MSTEST0067
Title Unikaj synchronicznego blokowania wywołań w kodzie testowym
Kategoria Zastosowanie
Poprawka jest przełomowa lub nieprzełomowa Non-breaking
Domyślnie włączone No
domyślna ciężkość Informacje
wprowadzone w wersji 4.3.0
Czy istnieje poprawka kodu No

Uwaga / Notatka

Ta reguła jest dostępna od msTest 4.3. Jest ona domyślnie wyłączona. Jest włączane jako ostrzeżenie, gdy ustawiono <MSTestAnalysisMode>All</MSTestAnalysisMode>.

Przyczyna

Kod testowy używa synchronicznego wywołania blokującego, takiego jak Thread.Sleep, Task.Wait, Task.WaitAll, Task.WaitAny lub Task<TResult>.Result.

Reguła jest wyzwalana dla metod oznaczonych elementem TestMethodAttribute (w tym atrybutów niestandardowych, które po nim dziedziczą) oraz dla metod fixture oznaczonych elementami TestInitializeAttribute, TestCleanupAttribute, ClassInitializeAttribute, ClassCleanupAttribute, AssemblyInitializeAttribute, AssemblyCleanupAttribute, GlobalTestInitializeAttribute i GlobalTestCleanupAttribute.

Opis reguły

Blokowanie synchroniczne bieżącego wątku wewnątrz metod testowych lub klas testowych jest częstą przyczyną niestabilności testów, a także może prowadzić do zakleszczenia, gdy framework testowy uruchamia testy w kontekście synchronizacji wymagającym kooperacyjnego planowania. Preferuj await Task.Delay oczekiwania oparte na czasie i await zadanie, aby obserwować jego wynik.

[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);
}

Jak naprawić naruszenia

Użyj odpowiednika asynchronicznego:

[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);
}

Kiedy pomijać ostrzeżenia

Ta zasada jest domyślnie wyłączona. Po włączeniu tej opcji pomijaj poszczególne wystąpienia, gdy synchroniczne oczekiwanie jest zamierzone i nie da się go uniknąć — na przykład przy korzystaniu z synchronicznego interfejsu API, którego nie da się przekształcić na asynchroniczny.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

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

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

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

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.