Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Usare le classi Assert dello spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting per verificare funzionalità specifiche. Un metodo di test esegue il codice nell'applicazione ma segnala la correttezza solo quando si includono Assert istruzioni.
Informazioni generali
MSTest offre tre classi di asserzione:
| Class | Scopo |
|---|---|
Assert |
Asserzioni per utilizzo generico per valori, tipi ed eccezioni. |
StringAssert |
Asserzioni specifiche della stringa per modelli, sottostringhe e confronti. |
CollectionAssert |
Asserzioni di raccolta per il confronto e la convalida delle raccolte. |
Importante
Per il nuovo codice, usare sempre la Assert classe . Le classi StringAssert e CollectionAssert saranno probabilmente deprecate in una prossima versione. Vengono mantenuti principalmente per la compatibilità con le versioni precedenti, ma non sono consigliati perché la suddivisione delle asserzioni in tre tipi fa male all'individuabilità.
Tutti i metodi di asserzione accettano un parametro di messaggio facoltativo che viene visualizzato quando l'asserzione ha esito negativo, consentendo di identificare la causa:
Assert.AreEqual(expected, actual, "Values should match after processing");
Classe Assert
Usare la classe Assert per verificare che il codice sottoposto a test si comporti come previsto.
Metodi di asserzione comuni
[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 disponibili
- 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
Asserzioni soft con Assert.Scope()
Importante
Assert.Scope() è un'API sperimentale. Usandolo viene generato il messaggio diagnostico MSTESTEXP, che è possibile sopprimere (ad esempio, con #pragma warning disable MSTESTEXP o nel file .editorconfig del progetto) per riconoscere esplicitamente che la struttura e il comportamento dell'API possono cambiare nelle versioni future.
Per impostazione predefinita, ogni asserzione genera un'eccezione AssertFailedException non appena ha esito negativo, che termina immediatamente il test.
Assert.Scope() introduce asserzioni soft: mentre un ambito è attivo, gli errori di asserzione vengono raccolti anziché generati, quindi l'esecuzione continua ed è possibile visualizzare ogni errore nell'ambito contemporaneamente. Quando lo scope viene rilasciato, gli errori raccolti vengono segnalati tutti insieme:
[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.
}
Quando l'ambito viene eliminato:
- Se è stata raccolta esattamente un'eccezione, viene generata quella originale
AssertFailedException. - Se sono stati raccolti più errori, viene generata un'unica
AssertFailedExceptionche li racchiude tutti in unAggregateException.
Le postcondizioni non vengono applicate all'interno di un ambito
Poiché un'asserzione con errori non viene più generata all'interno di un ambito, il codice eseguito dopo non può basarsi sull'asserzione che ha avuto esito positivo. Questo vale per ogni postcondizione, comprese la nullabilità e il restringimento del tipo:
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.
}
Se un'asserzione non riuscita portasse a un NullReferenceException (o a qualsiasi altra eccezione) in una riga successiva nell'ambito, tale eccezione secondaria è un sintomo del fallimento già registrato, non un bug separato. L'errore di asserzione originale viene comunque segnalato quando l'ambito viene eliminato.
Le asserzioni che restituiscono un valore restituiscono null/default in caso di errore all'interno di un ambito
Alcune asserzioni restituiscono un valore in caso di esito positivo, Throws ad esempio e ThrowsExactly restituiscono l'eccezione rilevata e ContainsSingle restituisce l'elemento corrispondente. Quando una di queste asserzioni ha esito negativo all'interno di un ambito, l'errore viene raccolto e il metodo restituisce null/default anziché generare:
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
}
Non fare affidamento sul valore restituito da un'asserzione soft all'interno di un ambito. Se è necessario il valore restituito ,ad esempio l'eccezione intercettata, chiamare l'asserzione all'esterno dell'ambito o ristrutturare il test in modo che nulla dipenda dal valore restituito fino a quando non viene eliminato l'ambito.
Assert.Fail e Assert.Inconclusive sempre lanciare
Fail e Inconclusive non sono mai morbidi. Vengono sempre sollevati immediatamente, anche all'interno di un ambito, poiché indicano un esito di test incondizionato. Usarne uno quando una condizione è critica e il resto del test non può continuare in modo significativo senza di esso.
Gli ambiti annidati non sono supportati
Non è possibile annidare le chiamate Assert.Scope(). Un solo ambito di asserzione può essere attivo alla volta.
Classe StringAssert
Usare la classe StringAssert per confrontare ed esaminare le stringhe.
Avvertimento
È probabile che la StringAssert classe sia deprecata in una versione futura. Viene mantenuto solo per la compatibilità con le versioni precedenti e non è consigliato per il nuovo codice. Tutti i StringAssert metodi hanno equivalenti nella Assert classe , che offre una migliore individuabilità. Per eseguire la migrazione degli utilizzi esistenti, vedere analizzatore MSTEST0046.
Le API disponibili sono:
- StringAssert.Contains
- StringAssert.DoesNotMatch
- StringAssert.EndsWith
- StringAssert.Matches
- StringAssert.StartsWith
Classe CollectionAssert
Usare la classe CollectionAssert per confrontare raccolte di oggetti o verificare lo stato di una raccolta.
Avvertimento
È probabile che la CollectionAssert classe sia deprecata in una versione futura. Viene gestito principalmente per la compatibilità con le versioni precedenti e non è consigliato per il nuovo codice. Quando esiste un metodo equivalente in Assert (ad esempio Assert.Contains, Assert.DoesNotContaino Assert.HasCount), usare Assert per una migliore individuabilità.
Le API disponibili sono:
- CollectionAssert.AllItemsAreInstancesOfType
- CollectionAssert.AllItemsAreNotNull
- CollectionAssert.AllItemsAreUnique
- CollectionAssert.AreEqual
- CollectionAssert.AreEquivalent
- CollectionAssert.AreNotEqual
- CollectionAssert.AreNotEquivalent
- CollectionAssert.Contains
- CollectionAssert.DoesNotContain
- CollectionAssert.IsNotSubsetOf
- CollectionAssert.IsSubsetOf
Creare asserzioni personalizzate con Assert.That
I metodi di asserzione predefiniti non coprono tutti gli scenari. Per estendere l'infrastruttura delle asserzioni con verifiche personalizzate, MSTest espone la proprietà singleton Assert.That come punto di estensione. Si aggiungono asserzioni personalizzate come metodi di estensione C# nel Assert tipo di istanza e i chiamanti li richiamano con la sintassi familiare Assert.That.MyAssertion(...) .
Per una migliore individuabilità, organizzare asserzioni a livello di progetto in una classe statica dedicata. Le asserzioni personalizzate accessibili tramite Assert.That vengono visualizzate insieme ai metodi predefiniti in IntelliSense, quindi gli utenti non devono ricordare un tipo di supporto separato.
Creare un'asserzione personalizzata
Aggiungere un metodo di estensione per il tipo Assert che solleva AssertFailedException quando la condizione non è soddisfatta:
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.");
}
}
}
Usare un'asserzione personalizzata
Dopo aver importato lo spazio dei nomi che contiene i metodi di estensione, chiama l'asserzione personalizzata tramite Assert.That:
[TestMethod]
public void Compute_ReturnsPrime()
{
int result = _calculator.NextPrime(10);
Assert.That.IsPrime(result);
}
Hook di estensione su StringAssert e CollectionAssert
Le proprietà StringAssert.That e CollectionAssert.That espongono lo stesso pattern singleton per garantire la compatibilità con le versioni precedenti. Per le nuove asserzioni personalizzate, specificare sempre come destinazione Assert.That. In caso contrario, i helper erediteranno gli stessi problemi di individuabilità delle classi legacy e dovranno essere migrati se StringAssert e CollectionAssert vengono deprecati.
Assert.That proprietà rispetto a Assert.That(...) metodo
Annotazioni
Non confondere la Assert.Thatproprietà singleton, usata come hook di estendibilità, con il Assert.That(() => condition)metodo aggiunto in MSTest 3.8. Quest'ultimo accetta un'espressione booleana e produce messaggi di errore dettagliati analizzando l'albero delle espressioni , ad esempio Assert.That(() => order.Total > 0). Le due API condividono un nome ma servono scopi diversi.
Procedure consigliate
Usare asserzioni specifiche: preferire
AreEqualIsTrue(a == b)per messaggi di errore migliori.Includere messaggi descrittivi: consente di identificare rapidamente gli errori con messaggi di asserzione chiari.
Testare una cosa alla volta: ogni metodo di test deve verificare un singolo comportamento.
Utilizzare
Throws/ThrowsExactlyper le eccezioni: in MSTest v3.8+, preferireAssert.Throws,Assert.ThrowsExactlye le relative controparti asincrone (ThrowsAsync,ThrowsExactlyAsync) sull'attributoExpectedException.Preferire
AssertaStringAssert/CollectionAssert: per una migliore rintracciabilità e coerenza, usare la classeAssert. Le classiStringAsserteCollectionAssertsaranno probabilmente deprecate in una prossima versione.Estendere
Assert.Thatper le asserzioni personalizzate: per un'individuabilità coerente, aggiungere asserzioni personalizzate come metodi di estensione suAsserte richiamarle tramiteAssert.That. Non specificare come destinazioneStringAssert.ThatoCollectionAssert.Thatnel nuovo codice.
Analizzatori correlati
Gli analizzatori seguenti consentono di garantire un uso appropriato delle asserzioni:
-
MSTEST0006 - evitare
ExpectedExceptionl'attributo, usare i metodiAssert.Throwsinvece. - MSTEST0017 : gli argomenti di asserzione devono essere passati nell'ordine corretto.
- MSTEST0023 : non negare le asserzioni booleane.
-
MSTEST0025 - Preferire
Assert.Failanziché condizioni sempre false. - MSTEST0026 : gli argomenti di asserzione devono evitare l'accesso condizionale.
- MSTEST0032 - Esaminare le condizioni di asserzione sempre vere.
- MSTEST0037 : usare metodi di asserzione appropriati.
-
MSTEST0038 : evitare
Assert.AreSamecon i tipi valore. -
MSTEST0039 : usare metodi più recenti
Assert.Throws. - MSTEST0040 : evitare di usare asserzioni nel contesto async void.
-
MSTEST0046 : usare
AssertanzichéStringAssert. -
-
Assert.ThrowsMSTEST0051 deve contenere una singola istruzione. -
MSTEST0053 : evitare
Assertparametri di formato. - MSTEST0058 : evitare asserzioni nei blocchi catch.