Attributi MSTest
MSTest usa attributi personalizzati per identificare e personalizzare i test.
Per offrire una panoramica più accurata del framework di testing, in questa sezione i membri dello spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting vengono organizzati in gruppi di funzionalità correlate.
Nota
Gli attributi, i cui nomi terminano con "Attribute", possono essere usati con o senza "Attribute" alla fine. Gli attributi con costruttore senza parametri possono essere scritti con o senza parentesi. Gli esempi di codice seguenti funzionano in modo identico:
[TestClass()]
[TestClassAttribute()]
[TestClass]
[TestClassAttribute]
Attributi usati per identificare classi e metodi di test
Ogni classe di test deve avere l'attributo TestClass
e ogni metodo di test deve avere l'attributo TestMethod
.
TestClassAttribute
L'attributo TestClass contrassegna una classe contenente test e, facoltativamente, metodi di inizializzazione o di pulizia.
Questo attributo può essere esteso per modificare o estendere il comportamento predefinito.
Esempio:
[TestClass]
public class MyTestClass
{
}
TestMethodAttribute
L'attributo TestMethod viene usato all'interno di un TestClass
per definire il metodo di test effettivo da eseguire.
Il metodo deve essere un metodo public
di istanza definito come void
, Task
o ValueTask
(a partire da MSTest v3.3). Facoltativamente, può essere async
, ma non deve essere async void
.
Il metodo deve avere parametri zero, a meno che non sia contrassegnato con l'attributo DataRow, l'attributo DynamicData o un attributo simile che fornisce dati del test case al metodo di test.
Si consideri la classe di test di esempio seguente:
[TestClass]
public class MyTestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Attributi usati per i test basati sui dati
Usare gli elementi seguenti per configurare test basati sui dati. Per altre informazioni, vedere Creare uno unit test basato sui dati e Usare un file di configurazione per definire un'origine dati.
DataRowAttribute
L'attributo DataRow consente di eseguire lo stesso metodo di test con più input diversi. Può apparire una o più volte in un metodo di test. Deve essere combinato con l'attributo TestMethod.
Il numero e i tipi di argomenti devono corrispondere esattamente alla firma del metodo di test. Si consideri l'esempio seguente di una classe di test valida che illustra l'utilizzo DataRowAttribute con argomenti inline allineati ai parametri del metodo di test:
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, "message", true, 2.0)]
public void TestMethod1(int i, string s, bool b, float f)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" })]
public void TestMethod2(string[] lines)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(null)]
public void TestMethod3(object o)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
public void TestMethod4(string[] input, string[] expectedOutput)
{
// Omitted for brevity.
}
}
Nota
È anche possibile usare la funzionalità params
per acquisire più input del DataRowAttribute.
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2, 3, 4)]
public void TestMethod(params int[] values) {}
}
Esempi di combinazioni non valide:
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2)] // Not valid, we are passing 2 inline data but signature expects 1
public void TestMethod1(int i) {}
[TestMethod]
[DataRow(1)] // Not valid, we are passing 1 inline data but signature expects 2
public void TestMethod2(int i, int j) {}
[TestMethod]
[DataRow(1)] // Not valid, count matches but types do not match
public void TestMethod3(string s) {}
}
Nota
A partire da MSTest v3, quando si vogliono passare esattamente 2 matrici, non è più necessario eseguire il wrapping della seconda matrice in una matrice di oggetti.
Prima:[DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })]
Avvio con v3:[DataRow(new string[] { "a" }, new string[] { "b" })]
È possibile modificare il nome visualizzato usato in Visual Studio e i logger per ogni istanza di DataRowAttribute impostando la proprietà DisplayName.
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2, DisplayName = "Functional Case FC100.1")]
public void TestMethod(int i, int j) {}
}
È anche possibile creare un attributo DataRow
specializzato ereditando il DataRowAttribute.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomDataRowAttribute : DataRowAttribute
{
}
[TestClass]
public class TestClass
{
[TestMethod]
[MyCustomDataRow(1)]
public void TestMethod(int i) {}
}
Attributi usati per fornire l'inizializzazione e le operazioni di pulizia
Le operazioni di impostazione e pulizia comuni a più test possono essere estratte in un metodo separato e contrassegnate con uno degli attributi elencati di seguito, per eseguirle al momento opportuno, ad esempio prima di ogni test. Per altre informazioni, vedere Anatomia di un unit test.
Livello di assembly
L'attributo AssemblyInitialize viene chiamato subito dopo il caricamento dell'assembly e l'attributo AssemblyCleanup viene chiamato subito prima che l'assembly venga scaricato.
I metodi contrassegnati con questi attributi devono essere definiti come static void
, static Task
o static ValueTask
(a partire da MSTest v3.3), in una classe contrassegnata con TestClassAttributee vengono visualizzati una sola volta. La parte di inizializzazione richiede un parametro di tipo TestContext e la pulizia non contiene parametri oppure a partire da MSTest 3.8 può avere un parametro di tipo TestContext.
[TestClass]
public class MyTestClass
{
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext testContext)
{
}
[AssemblyCleanup]
public static void AssemblyCleanup() // Starting with MSTest 3.8, it can be AssemblyCleanup(TestContext testContext)
{
}
}
Livello di classe
L'attributo ClassInitialize viene chiamato subito prima del caricamento della classe (ma dopo il costruttore statico) e il ClassCleanup viene chiamato subito dopo che la classe viene scaricata.
Importante
Per impostazione predefinita, ClassCleanupAttribute verrà attivato dopo l'ultimo test dell'assembly (in modo analogo a AssemblyCleanupAttribute). È possibile modificare questo comportamento impostando il CleanupBehavior sull'attributo . In alternativa, è possibile impostare questo comportamento a livello globale per l'assembly usando l'attributo assembly ClassCleanupExecutionAttribute.
È anche possibile controllare il comportamento di ereditarietà: solo per la classe corrente che usa InheritanceBehavior.Noneo per tutte le classi derivate che usano InheritanceBehavior.BeforeEachDerivedClass.
I metodi contrassegnati con questi attributi devono essere definiti come static void
, static Task
o static ValueTask
(a partire da MSTest v3.3), in un TestClass
e vengono visualizzati una sola volta. La parte di inizializzazione richiede un parametro di tipo TestContext e la pulizia non contiene parametri oppure a partire da MSTest 3.8 può avere un parametro di tipo TestContext.
[TestClass]
public class MyTestClass
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
}
[ClassCleanup]
public static void ClassCleanup() // Starting with MSTest 3.8, it can be ClassCleanup(TestContext testContext)
{
}
}
Livello di test
L'attributo TestInitialize viene chiamato subito prima dell'avvio del test e il TestCleanup viene chiamato subito dopo il completamento del test.
Il TestInitializeAttribute è simile al costruttore della classe, ma in genere è più adatto per inizializzazioni lunghe o asincrone. Il TestInitializeAttribute viene sempre richiamato dopo il costruttore ed eseguito per ogni test (inclusa ogni voce di test basato sui dati).
Il TestCleanupAttribute è simile alla classe Dispose
(o DisposeAsync
), ma in genere è più adatto per le pulizie lunghe o asincrone. Il TestCleanupAttribute viene sempre chiamato immediatamente prima del DisposeAsync
/Dispose
ed è chiamato per ciascun test (inclusa ogni voce dei test guidati dai dati ).
I metodi contrassegnati con questi attributi devono essere definiti come void
, Task
o ValueTask
(a partire da MSTest v3.3), in un TestClass
devono essere senza parametri e comparire una o più volte.
[TestClass]
public class MyTestClass
{
[TestInitialize]
public void TestInitialize()
{
}
[TestCleanup]
public void TestCleanup()
{
}
}
Attributi usati per controllare l'esecuzione dei test
Per modificare il modo in cui vengono eseguiti i test, è possibile usare gli attributi seguenti.
TimeoutAttribute
L'attributo Timeout può essere usato per specificare il tempo massimo in millisecondi consentito per l'esecuzione di un metodo di test. Se il metodo di test supera il tempo specificato, il test viene interrotto e contrassegnato come non riuscito.
Questo attributo può essere applicato a qualsiasi metodo di test o a qualsiasi metodo di fixture (metodi di inizializzazione e pulizia). È anche possibile specificare il timeout a livello globale per tutti i metodi di test o per tutti i metodi di fixture di test utilizzando le proprietà di timeout del file runsettings.
Nota
Non è garantito che il timeout sia preciso. Il test verrà interrotto dopo il superamento del tempo specificato, ma potrebbe richiedere più tempo prima dell'annullamento del passaggio.
Quando si usa la funzionalità di timeout, viene creato un thread/attività separato per eseguire il metodo di test. Il thread o l'attività principale è responsabile del monitoraggio del timeout e della disattivazione del thread o dell'attività del metodo se il timeout viene raggiunto.
A partire da MSTest 3.6, è possibile specificare la proprietà CooperativeCancellation sull'attributo (o a livello globale tramite runsettings) per abilitare l'annullamento cooperativo. In questa modalità, il metodo è responsabile del controllo del token di annullamento e dell'interruzione del test se viene segnalato come si farebbe in un tipico metodo di async
. Questa modalità è più efficiente e consente un controllo più preciso sul processo di annullamento. Questa modalità può essere applicata sia ai metodi asincroni che a quello di sincronizzazione.
STATestClassAttribute
Se applicato a una classe di test, l'attributo STATestClass indica che tutti i metodi di test (e i metodi [ClassInitialize]
e [ClassCleanup]
) nella classe devono essere eseguiti in un appartamento a thread singolo (STA). Questo attributo è utile quando i metodi di test interagiscono con oggetti COM che richiedono STA.
Nota
Questa funzionalità è supportata solo in Windows e nella versione 3.6 e successive.
STATestMethodAttribute
Se applicato a un metodo di test, l'attributo STATestMethod indica che il metodo di test deve essere eseguito in un appartamento a thread singolo (STA). Questo attributo è utile quando il metodo di test interagisce con oggetti COM che richiedono STA.
Nota
Questa funzionalità è supportata solo in Windows e nella versione 3.6 e successive.
ParallelizeAttribute
Per impostazione predefinita, MSTest esegue i test in ordine sequenziale. L'attributo a livello di assembly l'attributo Parallelize può essere usato per eseguire i test in parallelo. È possibile specificare se il parallelismo deve essere a livello di classe (è possibile eseguire più classi in parallelo, ma i test in una determinata classe vengono eseguiti in sequenza) o a livello di metodo.
È anche possibile specificare il numero massimo di thread da usare per l'esecuzione parallela. Un valore di 0
(valore predefinito) indica che il numero di thread è uguale al numero di processori logici nel computer.
È anche possibile specificare il parallelismo tramite le proprietà di parallelizzazione del file runsettings.
DoNotParallelizeAttribute
L'attributo DoNotParallelize può essere usato per impedire l'esecuzione parallela di test in un determinato assembly. Questo attributo può essere applicato a livello di assembly, livello di classe o di metodo.
Nota
Per impostazione predefinita, MSTest esegue i test in ordine sequenziale, pertanto è necessario usare questo attributo solo se è stato applicato il livello di assembly l'attributo Parallelize.
RetryAttribute
L'attributo Retry
è stato introdotto in MSTest 3.8. Questo attributo determina che il metodo di test venga ripetuto in caso di errore o timeout. Consente di specificare il numero massimo di tentativi di ripetizione, l'intervallo di tempo tra i tentativi e un tipo di backoff per l'attesa, che può essere costante o esponenziale.
È previsto che in un metodo di test sia presente un solo RetryAttribute
e RetryAttribute
non può essere usato nei metodi che non sono contrassegnati con TestMethod.
Nota
RetryAttribute
deriva da un RetryBaseAttribute
astratto. È anche possibile creare le proprie implementazioni di ritentativi se la funzionalità integrata RetryAttribute
predefinita non soddisfa le proprie esigenze.
Attributi di utilità
DeploymentItemAttribute
L'attributo DeploymentItem viene usato per copiare file o cartelle specificati come elementi di distribuzione nella directory di distribuzione (senza aggiungere un percorso di output personalizzato i file copiati saranno nella cartella TestResults
all'interno della cartella del progetto). La directory di distribuzione è la posizione in cui sono presenti tutti gli elementi di distribuzione insieme alla DLL del progetto di test.
Può essere usato nelle classi di test (classi contrassegnate con l'attributo TestClass) o nei metodi di test (metodi contrassegnati con attributo TestMethod).
Gli utenti possono avere più istanze dell'attributo per specificare più di un elemento.
Qui è possibile visualizzare i relativi costruttori.
Esempio
[TestClass]
[DeploymentItem(@"C:\classLevelDepItem.xml")] // Copy file using some absolute path
public class UnitTest1
{
[TestMethod]
[DeploymentItem(@"..\..\methodLevelDepItem1.xml")] // Copy file using a relative path from the dll output location
[DeploymentItem(@"C:\DataFiles\methodLevelDepItem2.xml", "SampleDataFiles")] // File will be added under a SampleDataFiles in the deployment directory
public void TestMethod1()
{
string textFromFile = File.ReadAllText("classLevelDepItem.xml");
}
}
Avviso
Non è consigliabile usare questo attributo per copiare i file nella directory di distribuzione.
ExpectedExceptionAttribute
L'attributo ExpectedException definisce l'eccezione che il metodo di test deve generare. Il test viene superato se viene generata l'eccezione prevista e il messaggio di eccezione corrisponde al messaggio previsto.
Avviso
Questo attributo esiste per la compatibilità con le versioni precedenti e non è consigliato per i nuovi test. Usare invece il metodo Assert.ThrowsException
(o il metodo Assert.ThrowsExactly
se si utilizza MSTest 3.8 o versioni successive).
Attributi dei metadati
I seguenti attributi e i valori ad essi assegnati sono visualizzati nella finestra Visual Studio
Proprietà di per un determinato metodo di test. Questi attributi non sono pensati per essere accessibili tramite il codice del test. Influiscono invece sui modi in cui viene usato o eseguito il test, ovvero manualmente tramite l'IDE di Visual Studio o dal motore di test di Visual Studio. Ad esempio, alcuni di questi attributi sono visualizzati come colonne nella finestra Gestione test e nella finestra Risultati del test, quindi è possibile usarli per raggruppare e ordinare i test e i risultati dei test. Uno di questi attributi è TestPropertyAttribute, che viene usato per aggiungere metadati arbitrari ai test.
È ad esempio possibile usarlo per archiviare il nome del superamento di un test coperto da questo test, contrassegnando il test con [TestProperty("Feature", "Accessibility")]
. In alternativa, è possibile usarlo per archiviare un indicatore del tipo di test con [TestProperty("ProductMilestone", "42")]
. La proprietà creata usando questo attributo e il valore di proprietà assegnato vengono entrambi visualizzati nella finestra Proprietà di Visual Studio, sotto l'intestazione Specifico del test.
- DescriptionAttribute
- IgnoreAttribute
- OwnerAttribute
- PriorityAttribute
- TestCategoryAttribute
- TestPropertyAttribute
- WorkItemAttribute
Gli attributi seguenti correlano il metodo di test che decorano alle entità nella gerarchia del progetto di un progetto team di Team Foundation Server
: