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.
Use las clases Assert del espacio de nombres Microsoft.VisualStudio.TestTools.UnitTesting para comprobar la funcionalidad específica. Un método de prueba ejecuta el código de la aplicación, pero notifica la corrección solo cuando se incluyen instrucciones Assert .
Información general
MSTest proporciona tres clases de aserción:
| Class | Propósito |
|---|---|
Assert |
Aserciones de uso general para valores, tipos y excepciones. |
StringAssert |
Aserciones específicas de cadenas para patrones, subcadenas y comparaciones. |
CollectionAssert |
Aserciones de colección para comparar y validar colecciones. |
Importante
Para el nuevo código, use siempre la Assert clase . Es probable que las StringAssert clases y CollectionAssert estén en desuso en una versión futura. Se mantienen principalmente por compatibilidad con versiones anteriores, pero no se recomiendan porque la división de aserciones entre tres tipos daña la detectabilidad.
Todos los métodos de aserción aceptan un parámetro de mensaje opcional que se muestra cuando se produce un error en la aserción, lo que le ayuda a identificar la causa:
Assert.AreEqual(expected, actual, "Values should match after processing");
La clase Assert.
Use la clase Assert para comprobar que el código sometido a prueba se comporta según lo previsto.
Métodos de aserción comunes
[TestMethod]
public async Task AssertExamples()
{
// Equality
Assert.AreEqual(5, calculator.Add(2, 3));
Assert.AreNotEqual(0, result);
// Reference equality
Assert.AreSame(expected, actual);
Assert.AreNotSame(obj1, obj2);
// Boolean conditions
Assert.IsTrue(result > 0);
Assert.IsFalse(string.IsNullOrEmpty(name));
// Null checks
Assert.IsNull(optionalValue);
Assert.IsNotNull(requiredValue);
// Type checks
Assert.IsInstanceOfType<IDisposable>(obj);
Assert.IsNotInstanceOfType<string>(obj);
// Exception testing (MSTest v3.8+)
Assert.ThrowsExactly<ArgumentNullException>(() => service.Process(null!));
await Assert.ThrowsExactlyAsync<InvalidOperationException>(
async () => await service.ProcessAsync());
}
API disponibles
- Assert.AreEqual
- Assert.AreNotEqual
- Assert.AreNotSame
- Assert.AreSame
- Assert.Contains
- Assert.ContainsSingle
- Assert.DoesNotContain
- Assert.DoesNotEndWith
- Assert.DoesNotMatchRegex
- Assert.DoesNotStartWith
- Assert.Fail
- Assert.HasCount
- Assert.Inconclusive
- Assert.IsEmpty
- Assert.IsFalse
- Assert.IsGreaterThan
- Assert.IsGreaterThanOrEqualTo
- Assert.IsInRange
- Assert.IsInstanceOfType
- Assert.IsLessThan
- Assert.IsLessThanOrEqualTo
- Assert.IsNegative
- Assert.IsNotEmpty
- Assert.IsNotInstanceOfType
- Assert.IsNotNull
- Assert.IsNull
- Assert.IsPositive
- Assert.IsTrue
- Assert.MatchesRegex
- Assert.StartsWith
- Assert.Throws
- Assert.ThrowsAsync
- Assert.ThrowsExactly
- Assert.ThrowsExactlyAsync
Aserciones no excluyentes con Assert.Scope()
Importante
Assert.Scope() es una API experimental. Su uso genera el diagnóstico MSTESTEXP, que debes suprimir (por ejemplo, con #pragma warning disable MSTESTEXP o en el archivo .editorconfig de tu proyecto) para reconocer que la estructura y el comportamiento de la API pueden cambiar en futuras versiones.
De forma predeterminada, cada aserción genera una excepción AssertFailedException en cuanto falla, lo que termina la prueba inmediatamente.
Assert.Scope() introduce aserciones no bloqueantes: mientras un ámbito está activo, los fallos de aserción se recopilan en lugar de lanzarse, por lo que la ejecución continúa y puedes ver todos los fallos del ámbito a la vez. Cuando se elimina el ámbito, los errores recopilados se notifican juntos:
[TestMethod]
public void ValidatePerson()
{
using (Assert.Scope())
{
Assert.AreEqual("Jane", person.FirstName); // failure collected, execution continues
Assert.AreEqual("Doe", person.LastName); // failure collected, execution continues
Assert.IsTrue(person.IsActive); // failure collected, execution continues
}
// On Dispose, all collected failures are reported together.
}
Cuando se elimina el ámbito:
- Si se detectó exactamente un fallo, se lanza el
AssertFailedExceptionoriginal. - Si se produjeron varios errores, se lanza un único
AssertFailedExceptionque los engloba a todos en unAggregateException.
Las condiciones posteriores no se aplican dentro de un ámbito
Como una aserción fallida ya no lanza una excepción dentro de un ámbito, el código que se ejecuta después no puede confiar en que la aserción se haya superado. Esto se aplica a cada condición posterior, incluida la nulabilidad y el restricción de tipos:
using (Assert.Scope())
{
Assert.IsNotNull(item);
// 'item' might still be null here: the failure was collected, not thrown.
Assert.AreEqual("expected", item.Value);
// 'item.Value' might not equal "expected" either.
}
Si una aserción con error provocaría NullReferenceException (o cualquier otra excepción) en una línea posterior dentro del ámbito, esa excepción secundaria es un síntoma del error ya recopilado, no un error independiente. El error de aserción original todavía se notifica cuando se elimina el ámbito.
Las aserciones de devolución de valores devuelven null/default en caso de error dentro de un ámbito
Algunas aserciones devuelven un valor en caso de éxito; por ejemplo, Throws y ThrowsExactly devuelven la excepción capturada, y ContainsSingle devuelve el elemento coincidente. Cuando se produce un error en una de estas aserciones dentro de un ámbito, se recopila el error y el método devuelve null/default en lugar de iniciar:
using (Assert.Scope())
{
// No exception is thrown by the lambda, so the assertion fails. The failure is
// collected and 'ex' is null. Accessing 'ex' below throws NullReferenceException.
InvalidOperationException ex = Assert.Throws<InvalidOperationException>(() => { });
_ = ex.Message; // NullReferenceException—don't use the return value in a scope
}
No confíe en el valor devuelto por una aserción no bloqueante dentro de un ámbito. Si necesita el valor devuelto (como la excepción detectada), llame a la aserción fuera del ámbito o reestructure la prueba para que nada dependa del valor devuelto hasta que se elimine el ámbito.
Assert.Fail y Assert.Inconclusive siempre lanzan una excepción
Fail y Inconclusive nunca son suaves. Siempre inician inmediatamente, incluso dentro de un ámbito, porque expresan un resultado de prueba incondicional. Use uno de ellos cuando una condición es crítica y el resto de la prueba no puede continuar significativamente sin ella.
No se admiten ámbitos anidados
No se pueden anidar llamadas Assert.Scope(). Solo un ámbito de aserción puede estar activo a la vez.
La clase StringAssert.
Use la clase StringAssert para comparar y examinar cadenas.
Advertencia
Es probable que la StringAssert clase esté en desuso en una versión futura. Solo se mantiene para la compatibilidad con versiones anteriores y no se recomienda para el nuevo código. Todos los StringAssert métodos tienen equivalentes en la Assert clase , lo que ofrece una mejor detectabilidad. Para migrar los usos existentes, consulte el analizador MSTEST0046.
Las API disponibles son:
- StringAssert.Contains
- StringAssert.DoesNotMatch
- StringAssert.EndsWith
- StringAssert.Matches
- StringAssert.StartsWith
La clase CollectionAssert.
Utilice la clase CollectionAssert para comparar colecciones de objetos o comprobar el estado de una colección.
Advertencia
Es probable que la CollectionAssert clase esté en desuso en una versión futura. Se mantiene principalmente por motivos de compatibilidad con versiones anteriores y no se recomienda para el nuevo código. Cuando existe un método equivalente en Assert (como Assert.Contains, Assert.DoesNotContaino Assert.HasCount), use Assert para mejorar la detectabilidad.
Las API disponibles son:
- CollectionAssert.AllItemsAreInstancesOfType
- CollectionAssert.AllItemsAreNotNull
- CollectionAssert.AllItemsAreUnique
- CollectionAssert.AreEqual
- CollectionAssert.AreEquivalent
- CollectionAssert.AreNotEqual
- CollectionAssert.AreNotEquivalent
- CollectionAssert.Contains
- CollectionAssert.DoesNotContain
- CollectionAssert.IsNotSubsetOf
- CollectionAssert.IsSubsetOf
Creación de aserciones personalizadas con Assert.That
Los métodos de aserción integrados no cubren todos los escenarios. Para ampliar la infraestructura de aserción con sus propias comprobaciones, MSTest expone la Assert.That propiedad singleton como un enlace de extensibilidad. Las aserciones personalizadas se agregan como métodos de extensión de C# en el Assert tipo de instancia y los autores de llamadas los invocan con la sintaxis conocida Assert.That.MyAssertion(...) .
Para mejorar la detectabilidad, organice las aserciones en todo el proyecto en una clase estática dedicada. Las aserciones personalizadas accesibles mediante Assert.That aparecen junto a los métodos integrados en IntelliSense, por lo que los usuarios no tienen que recordar un tipo auxiliar independiente.
Creación de una aserción personalizada
Agregue un método de extensión que tenga como destino el Assert tipo e inicie AssertFailedException cuando se produce un error en la condición:
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public static class CustomAssertExtensions
{
public static void IsPrime(this Assert assert, int value)
{
if (value < 2 || Enumerable.Range(2, (int)Math.Sqrt(value) - 1).Any(i => value % i == 0))
{
throw new AssertFailedException($"Assert.That.IsPrime failed. Value <{value}> is not a prime number.");
}
}
}
Uso de una aserción personalizada
Después de importar el espacio de nombres que contiene sus métodos de extensión, invoque su aserción personalizada mediante Assert.That:
[TestMethod]
public void Compute_ReturnsPrime()
{
int result = _calculator.NextPrime(10);
Assert.That.IsPrime(result);
}
Enlaces de extensión en StringAssert y CollectionAssert
Las StringAssert.That propiedades y CollectionAssert.That exponen el mismo patrón singleton para la compatibilidad con versiones anteriores. Para las nuevas aserciones personalizadas, siempre tenga como destino Assert.That. De lo contrario, los asistentes heredan los mismos problemas de detectabilidad que las clases heredadas y necesitarán la migración si StringAssert y CollectionAssert están en desuso.
Assert.That propiedad frente a Assert.That(...) método
Nota:
No confunda la Assert.Thatpropiedad única (utilizada como punto de extensión) con el Assert.That(() => condition)método añadido en MSTest 3.8. Este último acepta una expresión booleana y genera mensajes de error detallados mediante el análisis del árbol de expresiones (por ejemplo, Assert.That(() => order.Total > 0)). Las dos API comparten un nombre, pero sirven para fines diferentes.
procedimientos recomendados
Usar aserciones específicas: se prefiere
AreEqualporIsTrue(a == b)mejores mensajes de error.Incluir mensajes descriptivos: ayude a identificar los errores rápidamente con mensajes de aserción claros.
Probar una cosa a la vez: cada método de prueba debe comprobar un solo comportamiento.
Uso
Throws/ThrowsExactlypara excepciones: en MSTest v3.8+, prefiereAssert.Throws,Assert.ThrowsExactlyy sus homólogos asincrónicos (ThrowsAsync,ThrowsExactlyAsync) sobre elExpectedExceptionatributo .Prefiera
Asserten lugar deStringAssert/CollectionAssert: para mejorar la capacidad de detección y la coherencia, use la claseAssert. Es probable que lasStringAssertclases yCollectionAssertestén en desuso en una versión futura.Extensión
Assert.Thatde aserciones personalizadas: para lograr una detectabilidad coherente, agregue aserciones personalizadas como métodos de extensión enAsserte invoquelas a través deAssert.That. No haga referencia aStringAssert.Thatni aCollectionAssert.Thaten código nuevo.
Analizadores relacionados
Los analizadores siguientes ayudan a garantizar el uso adecuado de las aserciones:
-
MSTEST0006 : evite
ExpectedExceptionel atributo , useAssert.Throwsmétodos en su lugar. - MSTEST0017 : los argumentos de aserción deben pasarse en el orden correcto.
- MSTEST0023: No niegue las afirmaciones booleanas.
-
MSTEST0025 - Se prefiere
Assert.Failen lugar de condiciones siempre falsas. - MSTEST0026 : los argumentos de aserción deben evitar el acceso condicional.
- MSTEST0032 - Revisar las condiciones de aserción que siempre son verdaderas.
- MSTEST0037 : use los métodos de aserción adecuados.
-
MSTEST0038 - Evite el uso de
Assert.AreSamecon tipos de valor. -
MSTEST0039 : use métodos más recientes
Assert.Throws. - MSTEST0040: evite el uso de aserciones en contexto de void asincrónico.
-
MSTEST0046: use
Asserten lugar deStringAssert. -
-
Assert.ThrowsMSTEST0051 debe contener una sola instrucción. -
MSTEST0053 : evite
Assertlos parámetros de formato. - MSTEST0058: evite aserciones en bloques catch.