Uruchamianie i kontrola testów w MSTest

Narzędzie MSTest udostępnia atrybuty do kontrolowania sposobu wykonywania testów, w tym przetwarzania równoległego, modeli wątków, limitów czasu, ponawiania prób i wykonywania warunkowego na podstawie platformy lub środowiska.

Atrybuty wątkowania

Atrybuty wątków kontrolują model wątku, którego używają metody testowe. Te atrybuty są niezbędne podczas testowania składników COM, elementów interfejsu użytkownika lub kodu z określonymi wymaganiami wątkowymi.

STATestClassAttribute

Urządzenie STATestClassAttribute uruchamia wszystkie metody testowe w klasie (w tym ClassInitialize i ClassCleanup) w mieszkaniu jednowątkowym (STA). Użyj tego atrybutu podczas testowania obiektów COM, które wymagają sta.

[STATestClass]
public class ComInteropTests
{
    [TestMethod]
    public void TestComComponent()
    {
        // This test runs in an STA thread
        var comObject = new SomeComObject();
        // Test COM interactions
    }
}

Uwaga / Notatka

Ten atrybut jest obsługiwany tylko w systemie Windows w programie MSTest w wersji 3.6 lub nowszej.

STATestMethodAttribute

Uruchamia STATestMethodAttribute określoną metodę testową w jednym wątkowym mieszkaniu. Użyj tego atrybutu dla poszczególnych testów, które potrzebują STA, podczas gdy inne testy w tej klasie tego nie potrzebują.

[TestClass]
public class MixedThreadingTests
{
    [STATestMethod]
    public void TestRequiringSTA()
    {
        // This test runs in an STA thread
    }

    [TestMethod]
    public void RegularTest()
    {
        // This test uses default threading
    }
}

Uwaga / Notatka

Ten atrybut jest obsługiwany tylko w systemie Windows w programie MSTest w wersji 3.6 lub nowszej.

Zachowywanie kontekstu STA dla kontynuacji asynchronicznych

Począwszy od MSTest 4.1, element STATestMethodAttribute zawiera właściwość UseSTASynchronizationContext, która zapewnia, że kontynuacje asynchroniczne są uruchamiane w tym samym wątku STA. Po włączeniu atrybut tworzy niestandardowy SynchronizationContext element, który publikuje kontynuacje wątku STA, co jest niezbędne do testowania składników interfejsu użytkownika, które wymagają wątkowania STA w ramach operacji asynchronicznych.

[TestClass]
public class UIComponentTests
{
    [STATestMethod(UseSTASynchronizationContext = true)]
    public async Task TestAsyncUIOperation()
    {
        // Initial code runs on STA thread
        var control = new MyControl();
        
        await control.LoadDataAsync();
        
        // Continuation also runs on STA thread,
        // ensuring UI operations remain valid
        Assert.IsTrue(control.IsDataLoaded);
    }
}

Wskazówka

Użyj UseSTASynchronizationContext = true podczas testowania składników Windows Forms lub WPF, które wykonują operacje asynchroniczne i oczekują kontynuacji działania w tym samym wątku.

UITestMethodAttribute

Atrybut UITestMethod planuje wykonywanie testów w wątku interfejsu użytkownika. Ten atrybut jest przeznaczony do testowania aplikacji UWP i WinUI, które wymagają dostępu do wątku interfejsu użytkownika.

[TestClass]
public class WinUITests
{
    [UITestMethod]
    public void TestUIComponent()
    {
        // This test runs on the UI thread
        var button = new Button();
        button.Content = "Click me";
        Assert.IsNotNull(button.Content);
    }
}

Uwaga / Notatka

Ten atrybut wymaga odpowiedniego adaptera MSTest dla platform UWP lub WinUI. Aby uzyskać więcej informacji, zobacz sekcję pomocy technicznej platformy .

Atrybuty równoległościowe

Atrybuty przetwarzania równoległego określają, czy i jak testy są uruchamiane współbieżnie, poprawiając czas wykonywania testu.

ParallelizeAttribute

Domyślnie narzędzie MSTest uruchamia testy sekwencyjnie. Atrybut ParallelizeAttribute na poziomie zestawu umożliwia równoległe wykonywanie testów.

using Microsoft.VisualStudio.TestTools.UnitTesting;

[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]

Zakres przetwarzania równoległego

Scope Zachowanie
ClassLevel Wiele klas testowych jest uruchamianych równolegle, ale testy w obrębie klasy są uruchamiane sekwencyjnie.
MethodLevel Poszczególne metody testowe mogą być uruchamiane równolegle, niezależnie od ich klasy

Wątki robocze

Właściwość Workers określa maksymalną liczbę wątków do wykonywania równoległego:

  • 0 (ustawienie domyślne): użyj liczby procesorów logicznych na maszynie
  • Dowolna dodatnia liczba całkowita: użyj tej konkretnej liczby wątków
// Parallelize at class level with 2 worker threads
[assembly: Parallelize(Workers = 2, Scope = ExecutionScope.ClassLevel)]

Wskazówka

Możesz skonfigurować wykonywanie równoległe bez modyfikowania kodu za pomocą runsettings, testconfig.json lub właściwości MSBuild MSTestParallelizeScope i MSTestParallelizeWorkers.

Wskazówka

Domyślnie włącz równoległość na poziomie kompilacji, nawet jeśli wiele testów wymaga wykonywania sekwencyjnego. Takie podejście zachęca do pisania nowych testów, które obsługują wykonywanie równoległe od samego początku. Użyj analizatora MSTEST0001, aby upewnić się, że zestaw jawnie deklaruje intencję równoległości za pomocą [assembly: Parallelize] lub [assembly: DoNotParallelize]. Po włączeniu przetwarzania równoległego przejrzyj poszczególne klasy testowe, aby określić, czy bezpiecznie obsługuje wykonywanie współbieżne. Często wykluczenie tylko kilku klas lub metod z DoNotParallelize jest wystarczające, dzięki czemu większość testów może być uruchamiana równolegle w celu znacznie szybszego wykonywania testów.

DoNotParallelizeAttribute

Funkcja DoNotParallelizeAttribute zapobiega równoległym wykonywaniu określonych zestawów, klas lub metod. Użyj tego atrybutu, gdy testy współdzielą stan lub zasoby, do których nie można bezpiecznie uzyskiwać dostępu współbieżnego.

[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]

[TestClass]
public class ParallelTests
{
    [TestMethod]
    public void CanRunInParallel()
    {
        // This test can run with others
    }
}

[TestClass]
[DoNotParallelize]
public class SequentialTests
{
    [TestMethod]
    public void MustRunSequentially()
    {
        // This class's tests run sequentially
    }
}

[TestClass]
public class MixedTests
{
    [TestMethod]
    public void CanRunInParallel()
    {
        // This test can run with others
    }

    [TestMethod]
    [DoNotParallelize]
    public void MustBeIsolated()
    {
        // This specific test doesn't run in parallel
    }
}

Uwaga / Notatka

Wystarczy DoNotParallelize tylko wtedy, gdy włączono wykonywanie równoległe z atrybutem Parallelize .

ResourceLockAttribute

Ważna

ResourceLockAttribute Program jest planowany dla programu MSTest 4.4 i jest dostępny tylko w kompilacjach w wersji zapoznawczej do momentu wydania programu MSTest 4.4.0.

Służy [ResourceLock] do serializacji tylko testów, które uzyskują dostęp do tego samego nazwanego zasobu. W przeciwieństwie do [DoNotParallelize], blokada zasobu nie blokuje testów, które korzystają z niepowiązanych zasobów. Tryb domyślny ReadWrite jest wyłączny, podczas gdy wiele testów, które żądają ResourceAccessMode.Read tego samego zasobu, można uruchomić razem.

private const string Database = "integration-database";

[TestMethod]
[ResourceLock(Database, Mode = ResourceAccessMode.Read)]
public void ReadsSharedSchema() { }

W przypadku stanu dla całego procesu użyj stałych w WellKnownResources: CurrentDirectory, EnvironmentVariables i Console. Nazwy blokad wykorzystują porównanie porządkowe z rozróżnianiem wielkości liter i synchronizują testy wyłącznie w obrębie jednego źródła testów lub jednego zestawu. Nie koordynują testów z oddzielnych zestawów, procesów ani maszyn, nawet jeśli te testy korzystają z tego samego klucza.

Zakres blokady jest zgodny ze skonfigurowanym zakresem przetwarzania równoległego:

  • W przypadku ClassLevel MSTest łączy wszystkie blokady zadeklarowane w klasie i jej metodach, a następnie utrzymuje najsilniejszy tryb przez cały cykl życia klasy.
  • Dzięki MethodLevel, MSTest zakłada blokady dla każdego testu, w tym podczas inicjalizacji i czyszczenia tego testu.
  • Gdy równoległe działanie jest wyłączone, blokady zasobów nie mają wpływu.

Jeśli test używa także [DoNotParallelize], [DoNotParallelize] ma pierwszeństwo, a MSTest ignoruje jego blokady zasobów. Test, który czeka na dostępną blokadę zajmuje proces roboczy, więc rywalizacja o dużą liczbę blokad może nadal zmniejszyć przepływność.

Wskazówka

MSTest 4.4 dodaje analizatory bezpieczeństwa współbieżności od MSTEST0073 do MSTEST0077, aby ułatwić deklarowanie stabilnych kluczy blokad i ochronę współdzielonego stanu procesu.

Zależności testowe

Ważna

Zależności testowe są planowane dla programu MSTest 4.4 i są dostępne tylko w kompilacjach w wersji zapoznawczej do momentu wydania programu MSTest 4.4.0.

Użyj [DependsOn] do testów integracyjnych lub end-to-end, które muszą być uruchamiane po pozostałych testach. Zależności tworzą skierowany graf acykliczny, więc niezależne gałęzie mogą nadal działać równolegle.

[TestMethod]
public void CreateCart() { }

[TestMethod, DependsOn(nameof(CreateCart))]
public void PlaceOrder() { }

Zastosuj wiele atrybutów [DependsOn] dla fan-in lub zastosuj atrybut do kilku testów dla fan-out. Możesz odwołać się do metody w tej samej klasie, do każdego testu w innej klasie lub do jednej metody w innej klasie. Zastosuj [DependsOn] do klasy testowej, aby nadać każdemu testowi w tej klasie zależność. Gdy zależność jest przeznaczona dla testu opartego na danych, narzędzie MSTest czeka na wszystkie wiersze danych.

Domyślnie niespełnienie wymagania wstępnego powoduje pominięcie elementów od niego zależnych, a to pominięcie jest propagowane dalej. MSTest ocenia ProceedOnFailure dla każdego testu zależnego, a nie dla każdej krawędzi. Aby uruchomić element zależny po niespełnieniu wymagań wstępnych, ustaw ProceedOnFailure = true w każdej deklaracji [DependsOn] tego testu. Pozostawienie jednej deklaracji z wartością domyślną powoduje, że MSTest pomija test zależny. MSTest zgłasza cykle zależności przed uruchomieniem i oznacza testy w cyklu jako nieudane. Jeśli zależność nie jest częścią wybranego przebiegu, narzędzie MSTest ostrzega i ignoruje brakującą krawędź, aby filtry i przebiegi pojedynczego testu nadal działały.

Za pomocą Microsoft.Testing.Platform można również zadeklarować zależności w sekcji mstest.execution.dependencies w pliku testconfig.json:

  • Użyj chains do prostych sekwencji.
  • Użyj nodes dla fan-in, fan-out i proceedOnFailure.
{
  "mstest": { "execution": { "dependencies": {
    "chains": [["Contoso.Setup.CreateDatabase", "Contoso.Tests.ImportData"]],
    "nodes": [{ "test": "Contoso.Reports.*", "dependsOn": ["Contoso.Tests.ImportData"], "proceedOnFailure": true }]
  }}}
}

Odwołaj się do jednego testu za pomocą jego nazwy Namespace.Class.Method lub do wszystkich testów w klasie za pomocą Namespace.Class.*. Narzędzie MSTest scala zależności konfiguracji z zależnościami zadeklarowanymi za pomocą atrybutów.

Formularz testconfig.json działa tylko z Microsoft. Testing.Platform. Atrybut [DependsOn] działa zarówno z Microsoft.Testing.Platform, jak i z VSTest. W przypadku weryfikacji czasu kompilacji włącz MSTEST0078.

Wskazówka

Preferuj niezależne testy, urządzenia lub konfigurację dla testów jednostkowych. Zależności utrudniają uruchamianie testów w izolacji, dlatego należy je zarezerwować dla zestawów, w których sama sekwencja jest częścią scenariusza.

Atrybuty limitu czasu

Atrybuty limitu czasu uniemożliwiają uruchamianie testów na czas nieokreślony i pomagają identyfikować problemy z wydajnością.

TimeoutAttribute

Parametr TimeoutAttribute określa maksymalny czas (w milisekundach), który może uruchomić metoda testu lub urządzenia. Jeśli wykonanie przekroczy ten czas, test zakończy się niepowodzeniem.

[TestClass]
public class TimeoutTests
{
    [TestMethod]
    [Timeout(5000)] // 5 seconds
    public void TestWithTimeout()
    {
        // Test must complete within 5 seconds
    }
}

Wskazówka

Możesz skonfigurować globalny limit czasu testu za pomocą ustawień runsettings (TestTimeout) lub testconfig.json (timeout.test) bez modyfikowania kodu.

Zastosowanie limitu czasu do metod pomocniczych

Limity czasu można również zastosować do metod inicjalizacji i czyszczenia.

[TestClass]
public class FixtureTimeoutTests
{
    [ClassInitialize]
    [Timeout(10000)]
    public static void ClassInit(TestContext context)
    {
        // Must complete within 10 seconds
    }

    [TestInitialize]
    [Timeout(2000)]
    public void TestInit()
    {
        // Must complete within 2 seconds
    }
}

Wskazówka

Każda metoda fixture'a, która akceptuje atrybut [Timeout], ma równoważne globalne ustawienie konfiguracji. Skonfiguruj globalnie czas oczekiwania za pomocą runsettings lub testconfig.json przy użyciu ustawień, takich jak TestInitializeTimeout, ClassInitializeTimeout, AssemblyInitializeTimeout, i ich odpowiedniki oczyszczania.

Uwaga / Notatka

Czasowe limity nie gwarantują precyzyjności. Test przerywa się po upływie określonego czasu, ale rzeczywiste anulowanie może potrwać nieco dłużej.

Anulowanie współpracy

Domyślnie narzędzie MSTest umieszcza każdą metodę testową w osobnym zadaniu lub wątku. Po osiągnięciu limitu czasu struktura przestaje obserwować test, ale bazowe zadanie będzie nadal działać w tle. To zachowanie może powodować problemy:

  • Metoda testowa nadal uzyskuje dostęp do zasobów i zmienia stan nawet po przekroczeniu limitu czasu.
  • Wykonywanie w tle może prowadzić do warunków wyścigu wpływających na kolejne testy.
  • Każda metoda czasowa wiąże się z dodatkowym narzutem związanym z opakowaniem zadań lub wątków.

Począwszy od msTest 3.6, użyj CooperativeCancellation właściwości , aby uniknąć tych problemów. W trybie kooperacyjnym narzędzie MSTest nie zawija testu w dodatkowe zadanie. Zamiast tego po osiągnięciu limitu czasu platforma sygnalizuje token anulowania. Kod testowy jest odpowiedzialny za regularne sprawdzanie tokenu i łagodne zakończenie działania.

[TestClass]
public class CooperativeTimeoutTests
{
    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public async Task TestWithCooperativeCancellation(CancellationToken cancellationToken)
    {
        // Check the token periodically
        while (!cancellationToken.IsCancellationRequested)
        {
            await Task.Delay(100, cancellationToken);
            // Do work
        }
    }

    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public void SyncTestWithCooperativeCancellation(CancellationToken cancellationToken)
    {
        // Works with sync methods too
        for (int i = 0; i < 1000; i++)
        {
            cancellationToken.ThrowIfCancellationRequested();
            // Do work
        }
    }
}

Korzyści wynikające z anulowania współpracy:

  • Mniejsze obciążenie wydajności (bez dodatkowej nakładki zadań/wątków na test).
  • Skuteczniejsze czyszczenie zasobów, ponieważ kod jawnie obsługuje anulowanie.
  • Jest zgodny ze standardowymi wzorcami anulowania platformy .NET.
  • Zachowanie deterministyczne dzięki unikaniu warunków wyścigu między kodem testowym a nieobserwowanym wykonywaniem w tle.

Uwaga / Notatka

Współpracujące anulowanie wymaga, aby kod testowy regularnie sprawdzał token anulowania. Jeśli kod nie sprawdzi tokenu, test nie zostanie zatrzymany po osiągnięciu limitu czasu.

Wskazówka

Możesz włączyć globalne anulowanie współpracy dla wszystkich atrybutów limitu czasu za pomocą ustawień uruchamiania lub testconfig.json zamiast ustawiać je osobno dla każdego atrybutu.

Wskazówka

Powiązane analizatory:

  • MSTEST0045 — zaleca użycie anulowania kooperacyjnego dla atrybutów określających limit czasu.

Atrybuty ponawiania próby

Atrybuty ponawiania prób pomagają w obsłudze flakujących testów przez automatyczne ponowne uruchamianie testów, które zakończyły się niepowodzeniem.

RetryAttribute

Metoda RetryAttribute, wprowadzona w MSTest 3.8, automatycznie ponawia próby metod testowych, które kończą się niepowodzeniem lub przekroczeniem limitu czasu. Skonfiguruj maksymalną liczbę ponownych prób, opóźnienie między ponownymi próbami i strategię wycofywania.

[TestClass]
public class RetryTests
{
    [TestMethod]
    [Retry(3)] // Retry up to 3 times if the test fails
    public void FlakeyNetworkTest()
    {
        // Test that might occasionally fail due to network issues
    }

    [TestMethod]
    [Retry(3, MillisecondsDelayBetweenRetries = 1000, BackoffType = DelayBackoffType.Exponential)]
    public void TestWithExponentialBackoff()
    {
        // Retries with increasing delays: 1s, 2s, 4s
    }

    [TestMethod]
    [Retry(5, MillisecondsDelayBetweenRetries = 500, BackoffType = DelayBackoffType.Constant)]
    public void TestWithConstantDelay()
    {
        // Retries with constant 500ms delay between attempts
    }
}

Opcje konfiguracji

Majątek Description Default
MaxRetryAttempts Maksymalna liczba ponownych prób (tylko do odczytu, ustawiona za pomocą konstruktora) Required
MillisecondsDelayBetweenRetries Opóźnienie bazowe między ponownymi próbami (w ms) 0
BackoffType Constant lub Exponential opóźnienie Constant

Uwaga / Notatka

Tylko jeden RetryAttribute może być obecny w metodzie testowej. Nie można stosować RetryAttribute do metod, które nie są oznaczone słowem kluczowym TestMethod.

Uwaga / Notatka

Począwszy od msTest 4.3, RetryAttribute można również stosować na poziomie klasy testowej. Po zastosowaniu do klasy testowej ma zastosowanie do każdej metody testowej w klasie. Element RetryAttribute zastosowany do metody ma pierwszeństwo przed tym zastosowanym do klasy zawierającej tę metodę.

Począwszy od wersji MSTest 4.4 platforma Microsoft.Testing.Platform raportuje każdą ponowną próbę w wyjściu terminala oraz identyfikuje niestabilne testy i testy uruchamiane ponownie w podsumowaniu uruchomienia. Raporty CTRF zawierają szczegóły ponawiania prób. Raporty TRX i JUnit nadal zawierają jeden wynik końcowy na test, a zastąpione próby nie wpływają na kod zakończenia procesu.

Wskazówka

Powiązane analizatory:

  • MSTEST0043 — zaleca użycie RetryAttribute metod testowych.

Niestandardowe implementacje ponawiania prób

Począwszy od wersji MSTest 3.8 utwórz niestandardową logikę ponawiania przez dziedziczenie po RetryBaseAttribute:

Ważna

Interfejs RetryBaseAttribute.ExecuteAsync API i jego RetryContextRetryResult typy są eksperymentalne. Ich użycie powoduje wyświetlenie komunikatu diagnostycznego MSTESTEXP, którego przyjęcie należy potwierdzić przed użyciem interfejsu API.

Począwszy od wersji zapoznawczej MSTest 4.4, RetryResult.AllResults uwidacznia tablice wyników z każdej próby w kolejności, w której zostały dodane. MTP oznacza wcześniejsze próby jako zastąpione, natomiast VSTest otrzymuje wyłącznie wynik końcowy. Narzędzie MSTest ponawia próbę tylko wtedy, gdy próba zawiera wynik niepowodzenia lub przekroczenia limitu czasu. Sam wynik niejednoznaczny zatrzymuje sekwencję ponawiania.

Element --retry-failed-tests na poziomie procesu i atrybut ponawiania MSTest są stosowane na różnych poziomach. Ich efekty mają charakter multiplikatywny, ponieważ każda próba na poziomie procesu może uruchomić pełną sekwencję ponowień dla atrybutu.

public class CustomRetryAttribute : RetryBaseAttribute
{
    private readonly int _maxRetries;

    public CustomRetryAttribute(int maxRetries)
    {
        _maxRetries = maxRetries;
    }

    // Implement abstract members
    // Add custom logic for retry conditions
}

Atrybuty wykonywania warunkowego

Atrybuty warunkowego wykonywania określają, czy testy mają być uruchomione na podstawie określonych warunków, takich jak system operacyjny czy środowisko CI.

ConditionBaseAttribute

Jest ConditionBaseAttribute to abstrakcyjna klasa bazowa do wykonywania warunkowego. Narzędzie MSTest udostępnia kilka wbudowanych implementacji.

Uwaga / Notatka

Element ConditionBaseAttribute został wprowadzony w msTest 3.8.

Uwaga / Notatka

Domyślnie atrybuty warunku nie są dziedziczone. Zastosowanie ich do klasy bazowej nie ma wpływu na klasy pochodne. Atrybuty warunku niestandardowego mogą zastąpić to zachowanie przez ponowne zdefiniowanie AttributeUsage, ale nie jest to zalecane, aby zachować spójność z wbudowanymi atrybutami warunku.

Wskazówka

Powiązane analizatory:

  • MSTEST0041 — zaleca używanie atrybutów opartych na warunku z klasami testowymi.

OSConditionAttribute

Uruchamia lub pomija testy OSConditionAttribute na podstawie systemu operacyjnego. Użyj wyliczenia OperatingSystems flag, aby określić, które systemy operacyjne mają zastosowanie.

Uwaga / Notatka

Element OSConditionAttribute został wprowadzony w msTest 3.8.

[TestClass]
public class OSSpecificTests
{
    [TestMethod]
    [OSCondition(OperatingSystems.Windows)]
    public void WindowsOnlyTest()
    {
        // Runs only on Windows
    }

    [TestMethod]
    [OSCondition(OperatingSystems.Linux | OperatingSystems.OSX)]
    public void UnixLikeOnlyTest()
    {
        // Runs on Linux or macOS
    }

    [TestMethod]
    [OSCondition(ConditionMode.Exclude, OperatingSystems.Windows)]
    public void SkipOnWindowsTest()
    {
        // Runs on any OS except Windows
    }
}

Obsługiwane systemy operacyjne

System operacyjny Description
Windows Microsoft Windows
Linux Dystrybucje systemu Linux
OSX macOS
FreeBSD FreeBSD

Łączenie systemów operacyjnych z operatorem bitowym OR (|).

Wskazówka

Powiązane analizatory:

  • MSTEST0061 — zaleca użycie OSCondition atrybutu zamiast kontroli środowiska uruchomieniowego.

CIConditionAttribute

Uruchamia CIConditionAttribute lub pomija testy na podstawie tego, czy są wykonywane w ramach środowiska ciągłej integracji.

Uwaga / Notatka

Element CIConditionAttribute został wprowadzony w msTest 3.10.

[TestClass]
public class CIAwareTests
{
    [TestMethod]
    [CICondition(ConditionMode.Include)]
    public void CIOnlyTest()
    {
        // Runs only in CI environments
    }

    [TestMethod]
    [CICondition(ConditionMode.Exclude)]
    public void LocalDevelopmentOnlyTest()
    {
        // Skipped in CI, runs during local development
    }
}

MemberConditionAttribute

Element MemberConditionAttribute, wprowadzony w programie MSTest 4.3, uruchamia lub pomija klasę testową lub metodę testową na podstawie wartości co najmniej jednego statycznego bool elementu członkowskiego. Każda składowa jest identyfikowana przez typ, w którym została zadeklarowana, oraz nazwę i musi być typu public static, zwracać bool oraz (w przypadku metod) nie przyjmować parametrów. Jeśli określono kilka członów, są one łączone operatorem logicznym AND. Użyj polecenia ConditionMode , aby odwrócić warunek.

public static class TestConditions
{
    public static bool IsFeatureEnabled => true;
}

[TestClass]
public class FeatureTests
{
    [TestMethod]
    [MemberCondition(typeof(TestConditions), nameof(TestConditions.IsFeatureEnabled))]
    public void RunsWhenFeatureEnabled()
    {
    }

    [TestMethod]
    [MemberCondition(ConditionMode.Exclude, typeof(TestConditions), nameof(TestConditions.IsFeatureEnabled))]
    public void SkippedWhenFeatureEnabled()
    {
    }
}

Wskazówka

Powiązany analizator: argumenty MSTEST0070 - [MemberCondition] powinny być prawidłowe.

ArchitectureConditionAttribute

Element ArchitectureConditionAttribute, wprowadzony w programie MSTest 4.3, uruchamia lub pomija testy na podstawie architektury procesu. Użyj wyliczenia flagowego TestArchitectures, aby określić, które architektury obowiązują.

[TestClass]
public class ArchitectureTests
{
    [TestMethod]
    [ArchitectureCondition(TestArchitectures.X64)]
    public void RunsOnX64()
    {
    }

    [TestMethod]
    [ArchitectureCondition(ConditionMode.Exclude, TestArchitectures.X86)]
    public void SkippedOnX86()
    {
    }
}

ExecutableConditionAttribute

Element ExecutableConditionAttribute, wprowadzony w programie MSTest 4.3, uruchamia lub pomija testy na podstawie tego, czy narzędzie zewnętrzne jest dostępne. Test jest uruchamiany tylko wtedy, gdy można rozpoznać określony plik wykonywalny; Opcjonalnie można przekazać argumenty używane podczas sondowania narzędzia.

[TestClass]
public class ToolTests
{
    [TestMethod]
    [ExecutableCondition("git")]
    public void RunsWhenGitIsAvailable()
    {
    }

    [TestMethod]
    [ExecutableCondition("docker", "--version")]
    public void RunsWhenDockerResponds()
    {
    }
}

IgnoreAttribute

Bezwarunkowo IgnoreAttribute pomija klasę testową lub metodę. Opcjonalnie podaj przyczynę ignorowania.

Wskazówka

Powiązany analizator: MSTEST0015 — metoda testowa nie powinna być ignorowana. Włącz ten analizator, aby wykrywać testy, które są trwale ignorowane.

[TestClass]
public class IgnoreExamples
{
    [TestMethod]
    [Ignore]
    public void TemporarilyDisabled()
    {
        // This test is skipped
    }

    [TestMethod]
    [Ignore("Waiting for bug #123 to be fixed")]
    public void DisabledWithReason()
    {
        // This test is skipped with a documented reason
    }
}

[TestClass]
[Ignore("Entire class needs refactoring")]
public class IgnoredTestClass
{
    [TestMethod]
    public void Test1() { }  // Skipped

    [TestMethod]
    public void Test2() { }  // Skipped
}

Podczas ignorowania testów ze względu na znane problemy użyj polecenia WorkItemAttribute lub GitHubWorkItemAttribute w celu śledzenia:

[TestClass]
public class TrackedIgnoreExamples
{
    [TestMethod]
    [Ignore("Waiting for fix")]
    [WorkItem(12345)]
    public void TestWithWorkItem()
    {
        // Linked to work item 12345
    }

    [TestMethod]
    [Ignore("Known issue")]
    [GitHubWorkItem("https://github.com/owner/repo/issues/42")]
    public void TestWithGitHubIssue()
    {
        // Linked to GitHub issue #42
    }
}

Najlepsze rozwiązania

  1. Używaj równoległości mądrze: włącz równoległość dla niezależnych testów, ale użyj DoNotParallelize do testów, które współdzielą stan.

  2. Ustaw odpowiednie limity czasu: wybierz limity czasu, które umożliwiają normalne wykonanie, ale wykrywają zablokowane testy. Rozważ powolne środowiska ciągłej integracji.

  3. Preferuj anulowanie kooperacyjne: używaj anulowania kooperacyjnego, aby uniknąć narzutu nadmiarowych opakowań zadań i zapobiec wykonywaniu testów przekraczających czas w tle. Włącz analizator MSTEST0045 , aby wymusić tę praktykę.

  4. Dokumentowanie ignorowanych testów: zawsze podaj przyczynę i odniesienie do elementu roboczego podczas ignorowania testów.

  5. Użyj ponownych prób oszczędnie: rozwiąż główną przyczynę niestabilnych testów, a nie polegaj na ponownych próbach.

  6. Odpowiednio przetestuj kod specyficzny dla systemu operacyjnego: użyj polecenia OSCondition , aby uruchamiać testy specyficzne dla platformy tylko wtedy, gdy mają zastosowanie.

Zobacz także