Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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
STATestClassAttribute ejecuta todos los métodos de prueba de una clase (incluido ClassInitialize y ClassCleanup) en un apartamento con un único subproceso (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
STATestMethodAttribute ejecuta un método de prueba específico en un apartamento de un solo subproceso. 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 UseSTASynchronizationContext propiedad que garantiza que las continuaciones asincrónicas se ejecuten en el mismo hilo 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.
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
También puede configurar la paralelización mediante runsettings o testconfig.json sin modificar el código.
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 cada clase de prueba declara explícitamente su intención de paralelización, lo que le obliga a revisar si cada clase 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.
[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 ha habilitado la ejecución en paralelo con el Parallelize atributo .
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 precisamente 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 hilos.
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 suave.
[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
RetryAttribute, introducido 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.
Sugerencia
Analizadores relacionados:
-
MSTEST0043 : recomienda usar
RetryAttributeen métodos de prueba.
Implementaciones de reintento personalizadas
Cree lógica de reintento personalizada heredando de RetryBaseAttribute:
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:
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
Ejecuta OSConditionAttribute o omite pruebas basadas en el sistema operativo. Use la OperatingSystems enumeración flags para especificar qué sistemas operativos se aplican.
[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
OSConditionel 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.
[TestClass]
public class CIAwareTests
{
[TestMethod]
[CICondition] // Default: runs only in CI
public void CIOnlyTest()
{
// Runs only in CI environments
}
[TestMethod]
[CICondition(ConditionMode.Include)]
public void ExplicitCIOnlyTest()
{
// Same as above, explicitly stated
}
[TestMethod]
[CICondition(ConditionMode.Exclude)]
public void LocalDevelopmentOnlyTest()
{
// Skipped in CI, runs during local development
}
}
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
}
Enlace a elementos de trabajo
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
Use la paralelización sabiamente: habilite la paralelización para pruebas independientes, pero use
DoNotParallelizepara las pruebas que comparten el estado.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.
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.
Documentar pruebas ignoradas: Proporcione siempre una razón y una referencia al elemento de trabajo al ignorar las pruebas.
Use reintentos con moderación: solucione la causa principal de las pruebas poco confiables en lugar de depender de reintentos.
Probar el código específico del sistema operativo correctamente: use
OSConditionpara ejecutar pruebas específicas de la plataforma solo cuando sean aplicables.
Consulte también
- Configuración de MSTest
- Ciclo de vida de las pruebas
- Escritura de pruebas en MSTest
- MSTEST0001: Uso del atributo Parallelize
- MSTEST0041: Usar atributos basados en condiciones con la clase de prueba
- MSTEST0043: Uso del atributo retry en el método de prueba
- MSTEST0045: Uso de la cancelación cooperativa para el tiempo de espera
- MSTEST0059: Usar el atributo Parallelize correctamente
- MSTEST0061: usar el atributo OSCondition en lugar de la comprobación en tiempo de ejecución