Ejecución y control de pruebas en MSTest

MSTest proporciona atributos para controlar cómo se ejecutan las pruebas, incluida la paralelización, los modelos de subprocesos, los tiempos de espera, los reintentos y la ejecución condicional en función de la plataforma o el entorno.

Atributos de hilos

Los atributos de subproceso controlan qué métodos de prueba de modelo de subproceso usan. Estos atributos son esenciales al probar componentes COM, elementos de interfaz de usuario o código con requisitos específicos de subprocesos.

STATestClassAttribute

La STATestClassAttribute ejecuta todos los métodos de prueba de una clase (incluido ClassInitialize y ClassCleanup) en un contenedor uniproceso (STA). Use este atributo al probar objetos COM que requieren STA.

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

Nota:

Este atributo solo se admite en Windows en MSTest v3.6 y versiones posteriores.

STATestMethodAttribute

La STATestMethodAttribute ejecuta un método de prueba específico en un contenedor uniproceso. Use este atributo para pruebas individuales que necesitan STA mientras que otras pruebas de la clase no.

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

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

Nota:

Este atributo solo se admite en Windows en MSTest v3.6 y versiones posteriores.

Conservar el contexto STA para las continuaciones asincrónicas

A partir de MSTest 4.1, STATestMethodAttribute incluye la propiedad UseSTASynchronizationContext que garantiza que las continuaciones asincrónicas se ejecuten en el mismo subproceso STA. Cuando está habilitado, el atributo crea un SynchronizationContext personalizado que envía continuaciones al subproceso STA, lo cual es esencial para probar componentes de interfaz de usuario que requieren un subproceso STA durante sus operaciones asincrónicas.

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

Sugerencia

Se usa UseSTASynchronizationContext = true al probar componentes de Windows Forms o WPF que realizan operaciones asincrónicas y esperan que sus continuaciones se ejecuten en el mismo subproceso.

UITestMethodAttribute

El UITestMethod atributo programa la ejecución de pruebas en el subproceso de interfaz de usuario. Este atributo está diseñado para probar aplicaciones para UWP y WinUI que requieren acceso a subprocesos de interfaz de usuario.

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

Nota:

Este atributo requiere el adaptador MSTest adecuado para plataformas UWP o WinUI. Para obtener más información, consulte la sección compatibilidad con la plataforma .

Atributos de paralelización

Los atributos de paralelización controlan si y cómo se ejecutan las pruebas simultáneamente, lo que mejora el tiempo de ejecución de pruebas.

Configuración de la paralelización

MSTest ejecuta pruebas secuencialmente dentro de cada ensamblado de prueba de forma predeterminada. Use uno de los siguientes mecanismos para habilitar o deshabilitar explícitamente la paralelización en ensamblado:

Mecanismo Habilitación de la paralelización Deshabilitar la paralelización
Atributos de origen Aplique [assembly: Parallelize]y, opcionalmente, establezca su ámbito y recuento de trabajo. Aplique [assembly: DoNotParallelize] para deshabilitar la paralelización para el ensamblado. Aplicar [DoNotParallelize] a una clase o método para excluir solo esas pruebas después de habilitar la paralelización del ensamblado.
.runsettings Configure la entrada MSTestParallelize. Establece RunConfiguration.DisableParallelization en true. Esta configuración desactiva la paralelización incluso cuando el ensamblado tiene un atributo [Parallelize].
testconfig.json Establezca true en mstest.parallelism.enabled y, opcionalmente, configure scope y workers. Establece mstest.parallelism.enabled en false.
Propiedades de MSBuild Establezca MSTestParallelizeScope en ClassLevel o MethodLevely, opcionalmente, establezca MSTestParallelizeWorkers. Establece MSTestParallelizeScope en None. Estas propiedades generan el atributo de ensamblado correspondiente, por lo que no declare también el atributo en el origen.

ParallelizeAttribute

De forma predeterminada, MSTest ejecuta pruebas secuencialmente. El ParallelizeAttribute atributo de nivel de ensamblado habilita la ejecución de pruebas paralelas.

using Microsoft.VisualStudio.TestTools.UnitTesting;

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

Ámbito de paralelización

Ámbito Comportamiento
ClassLevel Varias clases de prueba se ejecutan en paralelo, pero las pruebas dentro de una clase se ejecutan secuencialmente
MethodLevel Los métodos de prueba individuales se pueden ejecutar en paralelo, independientemente de su clase.

Subprocesos de trabajo

La Workers propiedad especifica el número máximo de subprocesos para la ejecución en paralelo:

  • 0 (valor predeterminado): use el número de procesadores lógicos en la máquina.
  • Cualquier número entero positivo: utilice ese número específico de hilos.
// Parallelize at class level with 2 worker threads
[assembly: Parallelize(Workers = 2, Scope = ExecutionScope.ClassLevel)]

Sugerencia

Para elegir un mecanismo de configuración, consulte Configuración de la paralelización.

Sugerencia

Habilite la paralelización en el nivel de ensamblado de forma predeterminada, incluso si muchas pruebas requieren actualmente una ejecución secuencial. Este enfoque fomenta la escritura de nuevas pruebas que admiten la ejecución en paralelo desde el principio. Use el analizador de MSTEST0001 para asegurarse de que el ensamblado declara explícitamente su intención de paralelización con [assembly: Parallelize] o [assembly: DoNotParallelize]. Una vez habilitada la paralelización, revise cada clase de prueba para determinar si admite de forma segura la ejecución simultánea. A menudo, excluyendo solo algunas clases o métodos con DoNotParallelize es suficiente, lo que permite que la mayoría de las pruebas se ejecuten en paralelo para una ejecución de prueba significativamente más rápida.

DoNotParallelizeAttribute

El DoNotParallelizeAttribute impide la ejecución en paralelo de ensamblados, clases o métodos específicos. Use este atributo cuando las pruebas compartan el estado o los recursos a los que no se pueda acceder de forma segura simultáneamente.

Al habilitar la paralelización en ensamblado, MSTest crea particiones de cada origen de prueba (ensamblado) en pruebas paralelizables y no paralelizables. MSTest ejecuta primero el conjunto paralelizable y, a continuación, ejecuta el conjunto DoNotParallelize prueba a prueba al final de la ejecución de esa fuente. En ejecuciones que incluyen varios orígenes de prueba, cada origen tiene su propia cola diferida. Dado que las pruebas diferidas no pueden solaparse con otras pruebas en la misma fuente, una prueba diferida lenta suele aumentar la ruta crítica de esa fuente en aproximadamente su propia duración.

Dado que MSTest ejecuta pruebas diferidas solo después de que finalice la fase paralelizable, una ejecución cancelada o anulada puede finalizar antes de que MSTest ejecute pruebas diferidas. El orden de ejecución que se describe aquí es un detalle de implementación interno y no es un contrato público. Puede cambiar en una versión futura de MSTest.

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

Nota:

Solo necesita DoNotParallelize cuando haya habilitado la paralelización en ensamblado. Cuando la paralelización está deshabilitada (valor predeterminado), DoNotParallelize no tiene ningún efecto.

ResourceLockAttribute

Importante

ResourceLockAttribute está planeado para MSTest 4.4 y solo está disponible en compilaciones en versión preliminar hasta que se publique MSTest 4.4.0.

Use [ResourceLock] para serializar solo las pruebas que tienen acceso al mismo recurso con nombre. A diferencia de [DoNotParallelize], un bloqueo de un recurso no bloquea las pruebas que usan recursos no relacionados. El modo predeterminado ReadWrite es exclusivo, mientras que varias pruebas que solicitan ResourceAccessMode.Read el mismo recurso se pueden ejecutar juntas.

private const string Database = "integration-database";

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

Para el estado de todo el proceso, use las constantes de WellKnownResources: CurrentDirectory, EnvironmentVariablesy Console. Los nombres de los bloqueos utilizan pruebas de igualdad ordinal, con distinción entre mayúsculas y minúsculas, y de coordenadas únicamente dentro de una misma fuente de prueba o ensamblado. No coordinan las pruebas de ensamblados, procesos o máquinas independientes, incluso cuando esas pruebas usan la misma clave.

El ámbito de bloqueo sigue el ámbito de paralelización configurado:

  • Con ClassLevel, MSTest combina todos los bloqueos declarados en la clase y sus métodos y, a continuación, mantiene el modo más seguro para todo el ciclo de vida de la clase.
  • Con MethodLevel, MSTest adquiere bloqueos para cada prueba, incluidas su inicialización y limpieza.
  • Cuando la paralelización está deshabilitada, los bloqueos de recursos no tienen ningún efecto.

Si una prueba también usa [DoNotParallelize], [DoNotParallelize] tiene prioridad y MSTest omite sus bloqueos de recursos. Una prueba que espera un bloqueo contendiente ocupa un trabajo, por lo que la contención de bloqueo pesada todavía puede reducir el rendimiento.

Sugerencia

MSTest 4.4 agrega analizadores de seguridad en paralelo MSTEST0073 a través de MSTEST0077 para ayudarle a declarar claves de bloqueo estables y proteger el estado del proceso compartido.

Pruebas de dependencias

Importante

Las dependencias de prueba están planeadas para MSTest 4.4 y solo están disponibles en compilaciones en versión preliminar hasta que se publique MSTest 4.4.0.

Use [DependsOn] para la integración o las pruebas de un extremo a otro que deben ejecutarse después de otras pruebas. Las dependencias forman un grafo acíclico dirigido, por lo que las ramas independientes todavía se pueden ejecutar en paralelo.

[TestMethod]
public void CreateCart() { }

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

Aplique varios atributos [DependsOn] para fan-in, o aplique el atributo a varias pruebas para fan-out. Puede hacer referencia a un método de la misma clase, a todas las pruebas de otra clase o a un método de otra clase. Aplique [DependsOn] a una clase de prueba para proporcionar la dependencia a cada prueba de esa clase. Cuando una dependencia tiene como destino una prueba controlada por datos, MSTest espera todas sus filas de datos.

De forma predeterminada, si falla un prerrequisito, se omiten sus elementos dependientes, y la omisión se propaga. MSTest evalúa ProceedOnFailure por cada prueba dependiente, no por cada arista. Para ejecutar una prueba dependiente después de que hayan fallado los requisitos previos, establezca ProceedOnFailure = true en cada declaración [DependsOn] de esa prueba. Si se deja una declaración en el valor predeterminado, MSTest omite la dependiente. MSTest notifica ciclos de dependencia antes de la ejecución y produce un error en las pruebas del ciclo. Si una dependencia no forma parte de la ejecución seleccionada, MSTest advierte y omite el borde que falta, por lo que los filtros y las ejecuciones de prueba única siguen funcionando.

Con Microsoft.Testing.Platform, también puede declarar dependencias en mstest.execution.dependencies dentro de testconfig.json:

  • Se usa chains para secuencias rectas.
  • Utilice nodes para fan-in, fan-out y proceedOnFailure.
{
  "mstest": { "execution": { "dependencies": {
    "chains": [["Contoso.Setup.CreateDatabase", "Contoso.Tests.ImportData"]],
    "nodes": [{ "test": "Contoso.Reports.*", "dependsOn": ["Contoso.Tests.ImportData"], "proceedOnFailure": true }]
  }}}
}

Haga referencia a una prueba con su Namespace.Class.Method nombre o haga referencia a cada prueba de una clase con Namespace.Class.*. MSTest combina las dependencias de configuración con dependencias declaradas a través de atributos.

El testconfig.json formulario solo funciona con Microsoft. Testing.Platform. El [DependsOn] atributo funciona con ambos Microsoft. Testing.Platform y VSTest. Para la validación en tiempo de compilación, habilite MSTEST0078.

Sugerencia

Se prefieren pruebas independientes, accesorios o configuración por prueba para pruebas unitarias. Las dependencias hacen que las pruebas sean más difíciles de ejecutar de forma aislada, por lo que se reservan para conjuntos en los que la propia secuencia forma parte del escenario.

Atributos de tiempo de espera

Los atributos de tiempo de espera impiden que las pruebas se ejecuten indefinidamente y ayuden a identificar problemas de rendimiento.

TimeoutAttribute

TimeoutAttribute especifica el tiempo máximo (en milisegundos) durante el cual puede ejecutarse un método de prueba o de configuración. Si la ejecución supera este tiempo, se produce un error en la prueba.

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

Sugerencia

Puede configurar un tiempo de espera de prueba global a través de runsettings (TestTimeout) o testconfig.json (timeout.test) sin modificar el código.

Aplicar tiempo de espera a los métodos de prueba

También puede aplicar tiempos de espera a los métodos de inicialización y limpieza:

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

Sugerencia

Cada método de accesorio que acepta un [Timeout] atributo tiene una configuración global equivalente. Configure los tiempos de espera globalmente a través de runsettings o testconfig.json mediante configuraciones como TestInitializeTimeout, ClassInitializeTimeout, AssemblyInitializeTimeout y sus equivalentes de limpieza.

Nota:

No se garantiza que los tiempos de espera sean precisos. La prueba se anula una vez transcurrido el tiempo especificado, pero la cancelación real puede tardar un poco más.

Cancelación cooperativa

De forma predeterminada, MSTest encapsula cada método de prueba cronometrado en una tarea o subproceso independiente. Cuando se alcanza el tiempo de espera, el marco deja de observar la prueba, pero la tarea subyacente continúa ejecutándose en segundo plano. Este comportamiento puede causar problemas:

  • El método de prueba continúa accediendo a los recursos y mutando el estado incluso después del tiempo de espera.
  • La ejecución en segundo plano puede provocar condiciones de carrera que afecten a las pruebas posteriores.
  • Cada método temporizado incurre en una sobrecarga adicional del contenedor de tareas o subprocesos.

A partir de MSTest 3.6, use la CooperativeCancellation propiedad para evitar estos problemas. En modo cooperativo, MSTest no ajusta la prueba en una tarea adicional. En su lugar, cuando se alcanza el tiempo de espera, el framework señaliza el token de cancelación. El código de prueba es responsable de comprobar el token periódicamente y finalizar de manera correcta.

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

Beneficios de cancelación cooperativa:

  • Menor sobrecarga de rendimiento (sin contenedor adicional de tareas o subprocesos por prueba).
  • Limpieza de recursos más limpia, ya que el código controla la cancelación explícitamente.
  • Se alinea con los patrones de cancelación estándar de .NET.
  • Comportamiento determinista al evitar condiciones de carrera entre el código de prueba y la ejecución en segundo plano no observada.

Nota:

La cancelación cooperativa requiere que el código de prueba compruebe el token de cancelación con regularidad. Si el código no comprueba el token, la prueba no se detendrá realmente cuando se alcance el tiempo de espera.

Sugerencia

Puede habilitar la cancelación cooperativa globalmente para todos los atributos de tiempo de espera a través de runsettings o testconfig.json en lugar de establecerlo en cada atributo individualmente.

Sugerencia

Analizadores relacionados:

  • MSTEST0045 : recomienda usar la cancelación cooperativa para los atributos de tiempo de espera.

Atributos de reintento

Los atributos de reintento ayudan a controlar las pruebas poco confiables mediante la repetición automática de las pruebas con errores.

RetryAttribute

La RetryAttribute, introducida en MSTest 3.8, reintenta automáticamente los métodos de test que fallan o expiran. Configure los intentos de reintento máximos, los retrasos entre reintentos y la estrategia de backoff.

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

Opciones de configuración

Propiedad Description Predeterminado
MaxRetryAttempts Número máximo de reintentos (solo lectura, establecido a través del constructor) Obligatorio
MillisecondsDelayBetweenRetries Retraso base entre reintentos (en ms) 0
BackoffType Constant o Exponential retraso Constant

Nota:

Solo un RetryAttribute puede estar presente en un método de prueba. No se puede usar RetryAttribute en métodos que no estén marcados con TestMethod.

Nota:

A partir de MSTest 4.3, RetryAttribute también se puede aplicar en el nivel de clase de prueba. Cuando se aplica a una clase de prueba, se aplica a todos los métodos de prueba de la clase . Un RetryAttribute en un método tiene prioridad sobre uno de la clase contenedora.

A partir de MSTest 4.4, Microsoft.Testing.Platform informa de cada intento de reintento en la salida en el terminal e identifica las pruebas inestables y reintentadas en el resumen de la ejecución. Los informes de CTRF incluyen detalles de reintento. Los informes TRX y JUnit siguen conteniendo un resultado final por prueba y los intentos reemplazados no afectan al código de salida del proceso.

Sugerencia

Analizadores relacionados:

  • MSTEST0043 : recomienda usar RetryAttribute en métodos de prueba.

Implementaciones de reintento personalizadas

A partir de MSTest 3.8, cree lógica de reintento personalizada heredando de RetryBaseAttribute:

Importante

La API RetryBaseAttribute.ExecuteAsync y sus tipos RetryContext y RetryResult son experimentales. El uso de ellos genera el MSTESTEXP diagnóstico, que debe confirmar antes de usar la API.

A partir de la versión preliminar de MSTest 4.4, RetryResult.AllResults expone las matrices de resultados de cada intento en el orden en que se agregaron. MTP notifica los intentos anteriores como superados, mientras que VSTest recibe únicamente el resultado final. MSTest solo vuelve a intentarlo cuando un intento contiene un resultado fallido o que ha agotado el tiempo de espera. Un resultado inconclusivo por sí mismo detiene la secuencia de reintento.

El nivel --retry-failed-tests de proceso y un atributo de reintento de MSTest se aplican en distintos niveles. Sus efectos son multiplicativos porque cada intento de nivel de proceso puede ejecutar la secuencia de reintento completa del atributo.

public class CustomRetryAttribute : RetryBaseAttribute
{
    private readonly int _maxRetries;

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

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

Atributos para la ejecución condicional

Los atributos de ejecución condicional controlan si las pruebas se ejecutan en función de condiciones específicas, como el sistema operativo o el entorno de CI.

ConditionBaseAttribute

ConditionBaseAttribute es la clase base abstracta para la ejecución condicional. MSTest proporciona varias implementaciones integradas.

Nota:

ConditionBaseAttribute se introdujo en MSTest 3.8.

Nota:

De forma predeterminada, los atributos de condición no se heredan. Aplicarlos a una clase base no afecta a las clases derivadas. Los atributos de condición personalizados pueden invalidar este comportamiento redefinindo AttributeUsage, pero no se recomienda mantener la coherencia con los atributos de condición integrados.

Sugerencia

Analizadores relacionados:

  • MSTEST0041 : recomienda usar atributos basados en condiciones con clases de prueba.

OSConditionAttribute

La OSConditionAttribute ejecuta u omite pruebas basadas en el sistema operativo. Use la OperatingSystems enumeración flags para especificar qué sistemas operativos se aplican.

Nota:

OSConditionAttribute se introdujo en 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
    }
}

Sistemas operativos compatibles

Sistema operativo Description
Windows Microsoft Windows
Linux Distribuciones de Linux
OSX macOS
FreeBSD FreeBSD

Combine sistemas operativos con el operador OR bit a bit (|).

Sugerencia

Analizadores relacionados:

  • MSTEST0061 : recomienda usar OSCondition el atributo en lugar de las comprobaciones en tiempo de ejecución.

CIConditionAttribute

El componente CIConditionAttribute ejecuta o omite las pruebas en función de si se ejecutan en un entorno de integración continua.

Nota:

CIConditionAttribute se introdujo en 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

El MemberConditionAttribute, introducido en MSTest 4.3, ejecuta u omite una clase de prueba o un método de prueba en función del valor de uno o varios miembros bool estáticos. Se hace referencia a cada miembro mediante su declaración de tipo y nombre, y debe ser public static, devolver booly (para los métodos) sin parámetros. Cuando se especifican varios miembros, se combinan con un AND lógico. Use ConditionMode para invertir la condición.

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()
    {
    }
}

Sugerencia

Analizador relacionado: MSTEST0070 - [MemberCondition] argumentos deben ser válidos.

ArchitectureConditionAttribute

, ArchitectureConditionAttributeintroducido en MSTest 4.3, ejecuta o omite las pruebas en función de la arquitectura del proceso. Use la enumeración de marcas TestArchitectures para especificar qué arquitecturas son aplicables.

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

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

ExecutableConditionAttribute

, ExecutableConditionAttributeintroducido en MSTest 4.3, ejecuta o omite las pruebas en función de si hay disponible una herramienta externa. La prueba solo se ejecuta cuando se puede resolver el ejecutable especificado; Opcionalmente, puede pasar argumentos que se usan al sondear la herramienta.

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

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

IgnoreAttribute

El IgnoreAttribute omite incondicionalmente una clase o método de prueba. Opcionalmente, proporcione un motivo para omitir.

Sugerencia

Analizador relacionado: MSTEST0015 - No se debe omitir el método de prueba. Habilite este analizador para detectar pruebas que se omiten permanentemente.

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

Al omitir las pruebas debido a problemas conocidos, use WorkItemAttribute o GitHubWorkItemAttribute para la rastreabilidad:

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

procedimientos recomendados

  1. Use la paralelización sabiamente: habilite la paralelización para pruebas independientes, pero use DoNotParallelize para las pruebas que comparten el estado.

  2. Establecer tiempos de espera adecuados: elija tiempos de espera que permitan la ejecución normal, pero capturen pruebas bloqueadas. Considere los entornos de CI lentos.

  3. Preferir la cancelación cooperativa: Utilice la cancelación cooperativa para evitar la sobrecarga de envoltorios adicionales de tareas y prevenir la ejecución en segundo plano de pruebas que superan el tiempo límite. Habilite el analizador MSTEST0045 para aplicar esta práctica.

  4. Documentar pruebas ignoradas: Proporcione siempre una razón y una referencia al elemento de trabajo al ignorar las pruebas.

  5. Use reintentos con moderación: solucione la causa principal de las pruebas poco fiables en lugar de depender de reintentos.

  6. Probar el código específico del sistema operativo correctamente: use OSCondition para ejecutar pruebas específicas de la plataforma solo cuando sean aplicables.

Consulte también