Esercitazione: Testare una libreria di classi .NET con .NET usando Visual Studio
Questa esercitazione illustra come automatizzare gli unit test aggiungendo un progetto di test a una soluzione.
Prerequisiti
- Questa esercitazione funziona con la soluzione creata in Creare una libreria di classi .NET con Visual Studio.
Creare un progetto di unit test
Gli unit test forniscono test software automatici durante le fasi di sviluppo e pubblicazione. MSTest è uno dei tre framework di test tra cui è possibile scegliere. Gli altri sono xUnit e nUnit.
Avviare Visual Studio.
Aprire la soluzione
ClassLibraryProjects
creata in Creare una libreria di classi .NET usando Visual Studio.Aggiungere alla soluzione un nuovo progetto di unit test denominato "StringLibraryTest".
Fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni e selezionare Aggiungi>Nuovo progetto.
Nella pagina Aggiungi un nuovo progetto immettere mstest nella casella di ricerca. Scegliere C# o Visual Basic dall'elenco Linguaggio e quindi scegliere Tutte le piattaforme dall'elenco Piattaforma.
Scegliere il modello progetto di test MSTest e quindi scegliere Avanti.
Nella pagina Configura il nuovo progetto immettere StringLibraryTest nella casella Nome progetto. Scegliere quindi Avanti.
Nella pagina Informazioni aggiuntive selezionare .NET 8 (anteprima) nella casella Framework. Scegli quindi Crea.
Visual Studio crea il progetto e apre il file di classe nella finestra del codice con il codice seguente. Se il linguaggio che si vuole usare non viene visualizzato, modificare il selettore di linguaggio nella parte superiore della pagina.
namespace StringLibraryTest; [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Sub TestSub() End Sub End Class End Namespace
Il codice sorgente creato dal modello di unit test esegue le operazioni seguenti:
- Importa lo spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting, contenente i tipi usati per il testing unità. In C# lo spazio dei nomi viene importato tramite una direttiva
global using
in GlobalUsings.cs. - Applica l'attributo TestClassAttribute alla classe
UnitTest1
. - Applica l'attributo TestMethodAttribute per definire
TestMethod1
in C# oTestSub
in Visual Basic.
Ogni metodo contrassegnato con [TestMethod] in una classe di test contrassegnata con [TestClass] viene eseguito automaticamente quando viene eseguito lo unit test.
- Importa lo spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting, contenente i tipi usati per il testing unità. In C# lo spazio dei nomi viene importato tramite una direttiva
Aggiungere un riferimento al progetto
Affinché il progetto di test funzioni con la classe StringLibrary
, aggiungere un riferimento nel progetto StringLibraryTest al progetto StringLibrary
.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Dipendenze del progetto StringLibraryTest e selezionare Aggiungi riferimento al progetto dal menu di scelta rapida.
Nella finestra di dialogo Gestione riferimenti espandere il nodo Progetti e selezionare la casella accanto a StringLibrary. L'aggiunta di un riferimento all'assembly
StringLibrary
consente al compilatore di trovare i metodi StringLibrary durante la compilazione del progetto StringLibraryTest.Seleziona OK.
Aggiungere ed eseguire metodi di unit test
Quando Visual Studio esegue uno unit test, esegue ogni metodo contrassegnato con l'attributo TestMethodAttribute in una classe contrassegnata con l'attributo TestClassAttribute. Un metodo di test termina quando viene trovato il primo errore o quando tutti i test contenuti nel metodo hanno avuto esito positivo.
I test più comuni chiamano i membri della classe Assert. Molti metodi assert includono almeno due parametri, uno dei quali corrisponde al risultato previsto del test, mentre l'altro corrisponde al risultato effettivo. Nella tabella seguente sono illustrati alcuni metodi chiamati più frequentemente della classe Assert
:
Metodi Assert | Funzione |
---|---|
Assert.AreEqual |
Verifica che due oggetti o valori siano uguali. L'asserzione ha esito negativo se i valori o gli oggetti non sono uguali. |
Assert.AreSame |
Verifica che due variabili oggetto facciano riferimento allo stesso oggetto. Il metodo ha esito negativo se le variabili fanno riferimento a oggetti diversi. |
Assert.IsFalse |
Verifica che una condizione sia false . Il metodo ha esito negativo se la condizione è true . |
Assert.IsNotNull |
Verifica che un oggetto non sia null . Il metodo ha esito negativo se l'oggetto è null . |
È anche possibile usare il metodo Assert.ThrowsException in un metodo di test per indicare il tipo di eccezione che dovrebbe generare. Il test ha esito negativo se l'eccezione specificata non viene generata.
Durante il test del metodo StringLibrary.StartsWithUpper
, è possibile specificare alcune stringhe che iniziano con un carattere maiuscolo. In tal caso si prevede che il metodo restituisca true
, quindi è possibile chiamare il metodo Assert.IsTrue. Analogamente, è possibile specificare alcune stringhe che iniziano con un valore diverso da un carattere maiuscolo. In tal caso si prevede che il metodo restituisca false
, quindi è possibile chiamare il metodo Assert.IsFalse.
Poiché il metodo di libreria gestisce le stringhe, è anche necessario assicurarsi che gestisca correttamente una stringa vuota (String.Empty
), una stringa valida senza caratteri e il cui Length è 0 e una stringa null
che non è stata inizializzata. È possibile chiamare StartsWithUpper
direttamente come metodo statico e passare un singolo argomento String. In alternativa, è possibile chiamare StartsWithUpper
come metodo di estensione in una variabile di string
assegnata a null
.
Verranno definiti tre metodi, ognuno dei quali chiama un metodo Assert per ogni elemento in una matrice di stringhe. Verrà chiamato un overload del metodo che consente di specificare un messaggio di errore da visualizzare in caso di errore del test. Il messaggio identifica la stringa che ha causato l'errore.
Per creare i metodi di test:
Nella finestra del codice UnitTest1.cs o UnitTest1.vb sostituire il codice con il codice seguente:
using UtilityLibraries; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestStartsWithUpper() { // Tests that we expect to return true. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsTrue(result, string.Format("Expected for '{0}': true; Actual: {1}", word, result)); } } [TestMethod] public void TestDoesNotStartWithUpper() { // Tests that we expect to return false. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word, result)); } } [TestMethod] public void DirectCallWithNullOrEmpty() { // Tests that we expect to return false. string?[] words = { string.Empty, null }; foreach (var word in words) { bool result = StringLibrary.StartsWithUpper(word); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word == null ? "<null>" : word, result)); } } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports UtilityLibraries Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Public Sub TestStartsWithUpper() ' Tests that we expect to return true. Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}") Next End Sub <TestMethod> Public Sub TestDoesNotStartWithUpper() ' Tests that we expect to return false. Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " "} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}") Next End Sub <TestMethod> Public Sub DirectCallWithNullOrEmpty() ' Tests that we expect to return false. Dim words() As String = {String.Empty, Nothing} For Each word In words Dim result As Boolean = StringLibrary.StartsWithUpper(word) Assert.IsFalse(result, $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}") Next End Sub End Class End Namespace
Il test dei caratteri maiuscoli nel metodo
TestStartsWithUpper
include la lettera maiuscola greca alfa (U+0391) e la lettera maiuscola cirillico EM (U+041C). Il test dei caratteri minuscoli nel metodoTestDoesNotStartWithUpper
include la lettera minuscola greca alfa (U+03B1) e la lettera minuscola cirillico Ghe (U+0433).Nella barra dei menu selezionare File>Salva UnitTest1.cs con nome o File>Salva UnitTest1.vb con nome. Nella finestra di dialogo Salva file con nome selezionare la freccia accanto al pulsante Salva e selezionare Salva con codifica.
Nella finestra di dialogo Conferma Salva con nome selezionare il pulsante Sì per salvare il file.
Nella finestra di dialogo Opzioni di salvataggio avanzate selezionare Unicode (UTF-8 con firma digitale) - Tabella codici 65001 dall'elenco a discesa Codifica e selezionare OK.
Se il salvataggio del codice sorgente come file con codifica UTF8 ha esito negativo, Visual Studio può salvarlo come file ASCII. In questo caso, il runtime non decodifica accuratamente i caratteri UTF8 all'esterno dell'intervallo ASCII e i risultati del test non saranno corretti.
Nella barra dei menu selezionare Test>Esegui tutti i test. Se la finestra Esplora test non viene aperta, aprirla scegliendo Test>Esplora test. I tre test sono elencati nella sezione Test superati e nella sezione Riepilogo è riportato il risultato dell'esecuzione dei test.
Gestire gli errori di test
Se si esegue lo sviluppo basato su test (TDD), si scrivono prima i test e non riescono la prima volta che vengono eseguiti. Aggiungere quindi il codice all'app che rende il test riuscito. Per questa esercitazione è stato creato il test dopo aver scritto il codice dell'app convalidato, in modo da non aver visto l'esito negativo del test. Per verificare che un test non riesca quando si prevede che non riesca, aggiungere un valore non valido all'input di test.
Modificare la matrice
words
del metodoTestDoesNotStartWithUpper
per includere la stringa "Error". Non è necessario salvare il file perché Visual Studio salva i file aperti automaticamente quando viene creata una soluzione per eseguire i test.string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " };
Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }
Eseguire il test selezionando Test>Esegui tutti i test dalla barra dei menu. La finestra Esplora test indica che due test hanno avuto esito positivo e uno esito negativo.
Selezionare il test non riuscito,
TestDoesNotStartWith
.Nella finestra Esplora test viene visualizzato il messaggio generato dal metodo Assert: "Assert.IsFalse failed. Expected for 'Error': false; actual: True". A causa dell'errore, non sono state testate stringhe nella matrice dopo il test di "Error".
Rimuovere la stringa "Errore" aggiunta nel passaggio 1. Eseguire nuovamente il test. I test verranno superati.
Test della versione di rilascio della libreria
Ora che tutti i test sono stati superati durante l'esecuzione della compilazione Debug della libreria, eseguire i test un tempo aggiuntivo rispetto alla versione di rilascio della libreria. Esistono infatti alcuni fattori, ad esempio le ottimizzazioni del compilatore, in grado di generare a volte comportamenti diversi tra la versione di debug e quella di rilascio.
Per testare la versione di rilascio, seguire questa procedura:
Nella barra degli strumenti di Visual Studio modificare la configurazione di compilazione da Debug a Rilascio.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto StringLibrary e selezionare Compila dal menu di scelta rapida per ricompilare la libreria.
Eseguire gli unit test scegliendo Test>Esegui tutti i test dalla barra dei menu. I test avranno esito positivo.
Esecuzione del debug dei test
Se si usa Visual Studio come IDE, è possibile usare lo stesso processo illustrato in Esercitazione: Eseguire il debug di un'applicazione console .NET usando Visual Studio per eseguire il debug del codice usando il progetto di unit test. Invece di avviare il progetto di app ShowCase, fare clic con il pulsante destro del mouse sul progetto StringLibraryTests e scegliere Debug test dal menu di scelta rapida.
Visual Studio avvia il progetto di test con il debugger collegato. L'esecuzione verrà arrestata in qualsiasi punto di interruzione aggiunto al progetto di test o al codice della libreria sottostante.
Risorse aggiuntive
Passaggi successivi
In questa esercitazione è stata testata una libreria di classi. È possibile rendere disponibile la libreria ad altri utenti pubblicandola in NuGet come pacchetto. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Se si pubblica una libreria come pacchetto NuGet, altri utenti possono installarla e usarla. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Non è necessario distribuire una libreria come pacchetto. Può essere incluso in un'app console che la usa. Per informazioni su come pubblicare un'app console, vedere l'esercitazione precedente in questa serie:
Questa esercitazione illustra come automatizzare gli unit test aggiungendo un progetto di test a una soluzione.
Prerequisiti
- Questa esercitazione funziona con la soluzione creata in Creare una libreria di classi .NET con Visual Studio.
Creare un progetto di unit test
Gli unit test forniscono test software automatici durante le fasi di sviluppo e pubblicazione. MSTest è uno dei tre framework di test tra cui è possibile scegliere. Gli altri sono xUnit e nUnit.
Avviare Visual Studio.
Aprire la soluzione
ClassLibraryProjects
creata in Creare una libreria di classi .NET usando Visual Studio.Aggiungere alla soluzione un nuovo progetto di unit test denominato "StringLibraryTest".
Fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni e selezionare Aggiungi>Nuovo progetto.
Nella pagina Aggiungi un nuovo progetto immettere mstest nella casella di ricerca. Scegliere C# o Visual Basic dall'elenco Linguaggio e quindi scegliere Tutte le piattaforme dall'elenco Piattaforma.
Scegliere il modello progetto di test MSTest e quindi scegliere Avanti.
Nella pagina Configura il nuovo progetto immettere StringLibraryTest nella casella Nome progetto. Scegliere quindi Avanti.
Nella pagina Informazioni aggiuntive selezionare .NET 7 (supporto standard) nella casella Framework. Scegli quindi Crea.
Visual Studio crea il progetto e apre il file di classe nella finestra del codice con il codice seguente. Se il linguaggio che si vuole usare non viene visualizzato, modificare il selettore di linguaggio nella parte superiore della pagina.
using Microsoft.VisualStudio.TestTools.UnitTesting; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Sub TestSub() End Sub End Class End Namespace
Il codice sorgente creato dal modello di unit test esegue le operazioni seguenti:
- Importa lo spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting, contenente i tipi usati per il testing unità.
- Applica l'attributo TestClassAttribute alla classe
UnitTest1
. - Applica l'attributo TestMethodAttribute per definire
TestMethod1
in C# oTestSub
in Visual Basic.
Ogni metodo contrassegnato con [TestMethod] in una classe di test contrassegnata con [TestClass] viene eseguito automaticamente quando viene eseguito lo unit test.
Aggiungere un riferimento al progetto
Affinché il progetto di test funzioni con la classe StringLibrary
, aggiungere un riferimento nel progetto StringLibraryTest al progetto StringLibrary
.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Dipendenze del progetto StringLibraryTest e selezionare Aggiungi riferimento al progetto dal menu di scelta rapida.
Nella finestra di dialogo Gestione riferimenti espandere il nodo Progetti e selezionare la casella accanto a StringLibrary. L'aggiunta di un riferimento all'assembly
StringLibrary
consente al compilatore di trovare i metodi StringLibrary durante la compilazione del progetto StringLibraryTest.Seleziona OK.
Aggiungere ed eseguire metodi di unit test
Quando Visual Studio esegue uno unit test, esegue ogni metodo contrassegnato con l'attributo TestMethodAttribute in una classe contrassegnata con l'attributo TestClassAttribute. Un metodo di test termina quando viene trovato il primo errore o quando tutti i test contenuti nel metodo hanno avuto esito positivo.
I test più comuni chiamano i membri della classe Assert. Molti metodi assert includono almeno due parametri, uno dei quali corrisponde al risultato previsto del test, mentre l'altro corrisponde al risultato effettivo. Nella tabella seguente sono illustrati alcuni metodi chiamati più frequentemente della classe Assert
:
Metodi Assert | Funzione |
---|---|
Assert.AreEqual |
Verifica che due oggetti o valori siano uguali. L'asserzione ha esito negativo se i valori o gli oggetti non sono uguali. |
Assert.AreSame |
Verifica che due variabili oggetto facciano riferimento allo stesso oggetto. Il metodo ha esito negativo se le variabili fanno riferimento a oggetti diversi. |
Assert.IsFalse |
Verifica che una condizione sia false . Il metodo ha esito negativo se la condizione è true . |
Assert.IsNotNull |
Verifica che un oggetto non sia null . Il metodo ha esito negativo se l'oggetto è null . |
È anche possibile usare il metodo Assert.ThrowsException in un metodo di test per indicare il tipo di eccezione che dovrebbe generare. Il test ha esito negativo se l'eccezione specificata non viene generata.
Durante il test del metodo StringLibrary.StartsWithUpper
, è possibile specificare alcune stringhe che iniziano con un carattere maiuscolo. In tal caso si prevede che il metodo restituisca true
, quindi è possibile chiamare il metodo Assert.IsTrue. Analogamente, è possibile specificare alcune stringhe che iniziano con un valore diverso da un carattere maiuscolo. In tal caso si prevede che il metodo restituisca false
, quindi è possibile chiamare il metodo Assert.IsFalse.
Poiché il metodo di libreria gestisce le stringhe, è anche necessario assicurarsi che gestisca correttamente una stringa vuota (String.Empty
), una stringa valida senza caratteri e il cui Length è 0 e una stringa null
che non è stata inizializzata. È possibile chiamare StartsWithUpper
direttamente come metodo statico e passare un singolo argomento String. In alternativa, è possibile chiamare StartsWithUpper
come metodo di estensione in una variabile di string
assegnata a null
.
Verranno definiti tre metodi, ognuno dei quali chiama un metodo Assert per ogni elemento in una matrice di stringhe. Verrà chiamato un overload del metodo che consente di specificare un messaggio di errore da visualizzare in caso di errore del test. Il messaggio identifica la stringa che ha causato l'errore.
Per creare i metodi di test:
Nella finestra del codice UnitTest1.cs o UnitTest1.vb sostituire il codice con il codice seguente:
using Microsoft.VisualStudio.TestTools.UnitTesting; using UtilityLibraries; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestStartsWithUpper() { // Tests that we expect to return true. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsTrue(result, string.Format("Expected for '{0}': true; Actual: {1}", word, result)); } } [TestMethod] public void TestDoesNotStartWithUpper() { // Tests that we expect to return false. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word, result)); } } [TestMethod] public void DirectCallWithNullOrEmpty() { // Tests that we expect to return false. string?[] words = { string.Empty, null }; foreach (var word in words) { bool result = StringLibrary.StartsWithUpper(word); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word == null ? "<null>" : word, result)); } } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports UtilityLibraries Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Public Sub TestStartsWithUpper() ' Tests that we expect to return true. Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}") Next End Sub <TestMethod> Public Sub TestDoesNotStartWithUpper() ' Tests that we expect to return false. Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " "} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}") Next End Sub <TestMethod> Public Sub DirectCallWithNullOrEmpty() ' Tests that we expect to return false. Dim words() As String = {String.Empty, Nothing} For Each word In words Dim result As Boolean = StringLibrary.StartsWithUpper(word) Assert.IsFalse(result, $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}") Next End Sub End Class End Namespace
Il test dei caratteri maiuscoli nel metodo
TestStartsWithUpper
include la lettera maiuscola greca alfa (U+0391) e la lettera maiuscola cirillico EM (U+041C). Il test dei caratteri minuscoli nel metodoTestDoesNotStartWithUpper
include la lettera minuscola greca alfa (U+03B1) e la lettera minuscola cirillico Ghe (U+0433).Nella barra dei menu selezionare File>Salva UnitTest1.cs con nome o File>Salva UnitTest1.vb con nome. Nella finestra di dialogo Salva file con nome selezionare la freccia accanto al pulsante Salva e selezionare Salva con codifica.
Nella finestra di dialogo Conferma Salva con nome selezionare il pulsante Sì per salvare il file.
Nella finestra di dialogo Opzioni di salvataggio avanzate selezionare Unicode (UTF-8 con firma digitale) - Tabella codici 65001 dall'elenco a discesa Codifica e selezionare OK.
Se il salvataggio del codice sorgente come file con codifica UTF8 ha esito negativo, Visual Studio può salvarlo come file ASCII. In questo caso, il runtime non decodifica accuratamente i caratteri UTF8 all'esterno dell'intervallo ASCII e i risultati del test non saranno corretti.
Nella barra dei menu selezionare Test>Esegui tutti i test. Se la finestra Esplora test non viene aperta, aprirla scegliendo Test>Esplora test. I tre test sono elencati nella sezione Test superati e nella sezione Riepilogo è riportato il risultato dell'esecuzione dei test.
Gestire gli errori di test
Se si esegue lo sviluppo basato su test (TDD), si scrivono prima i test e non riescono la prima volta che vengono eseguiti. Aggiungere quindi il codice all'app che rende il test riuscito. Per questa esercitazione è stato creato il test dopo aver scritto il codice dell'app convalidato, in modo da non aver visto l'esito negativo del test. Per verificare che un test non riesca quando si prevede che non riesca, aggiungere un valore non valido all'input di test.
Modificare la matrice
words
del metodoTestDoesNotStartWithUpper
per includere la stringa "Error". Non è necessario salvare il file perché Visual Studio salva i file aperti automaticamente quando viene creata una soluzione per eseguire i test.string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " };
Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }
Eseguire il test selezionando Test>Esegui tutti i test dalla barra dei menu. La finestra Esplora test indica che due test hanno avuto esito positivo e uno esito negativo.
Selezionare il test non riuscito,
TestDoesNotStartWith
.Nella finestra Esplora test viene visualizzato il messaggio generato dal metodo Assert: "Assert.IsFalse failed. Expected for 'Error': false; actual: True". A causa dell'errore, non sono state testate stringhe nella matrice dopo il test di "Error".
Rimuovere la stringa "Errore" aggiunta nel passaggio 1. Eseguire nuovamente il test. I test verranno superati.
Test della versione di rilascio della libreria
Ora che tutti i test sono stati superati durante l'esecuzione della compilazione Debug della libreria, eseguire i test un tempo aggiuntivo rispetto alla versione di rilascio della libreria. Esistono infatti alcuni fattori, ad esempio le ottimizzazioni del compilatore, in grado di generare a volte comportamenti diversi tra la versione di debug e quella di rilascio.
Per testare la versione di rilascio, seguire questa procedura:
Nella barra degli strumenti di Visual Studio modificare la configurazione di compilazione da Debug a Rilascio.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto StringLibrary e selezionare Compila dal menu di scelta rapida per ricompilare la libreria.
Eseguire gli unit test scegliendo Test>Esegui tutti i test dalla barra dei menu. I test avranno esito positivo.
Esecuzione del debug dei test
Se si usa Visual Studio come IDE, è possibile usare lo stesso processo illustrato in Esercitazione: Eseguire il debug di un'applicazione console .NET usando Visual Studio per eseguire il debug del codice usando il progetto di unit test. Invece di avviare il progetto di app ShowCase, fare clic con il pulsante destro del mouse sul progetto StringLibraryTests e scegliere Debug test dal menu di scelta rapida.
Visual Studio avvia il progetto di test con il debugger collegato. L'esecuzione verrà arrestata in qualsiasi punto di interruzione aggiunto al progetto di test o al codice della libreria sottostante.
Risorse aggiuntive
Passaggi successivi
In questa esercitazione è stata testata una libreria di classi. È possibile rendere disponibile la libreria ad altri utenti pubblicandola in NuGet come pacchetto. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Se si pubblica una libreria come pacchetto NuGet, altri utenti possono installarla e usarla. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Non è necessario distribuire una libreria come pacchetto. Può essere incluso in un'app console che la usa. Per informazioni su come pubblicare un'app console, vedere l'esercitazione precedente in questa serie:
Questa esercitazione illustra come automatizzare gli unit test aggiungendo un progetto di test a una soluzione.
Prerequisiti
- Questa esercitazione funziona con la soluzione creata in Creare una libreria di classi .NET con Visual Studio.
Creare un progetto di unit test
Gli unit test forniscono test software automatici durante le fasi di sviluppo e pubblicazione. MSTest è uno dei tre framework di test tra cui è possibile scegliere. Gli altri sono xUnit e nUnit.
Avviare Visual Studio.
Aprire la soluzione
ClassLibraryProjects
creata in Creare una libreria di classi .NET usando Visual Studio.Aggiungere alla soluzione un nuovo progetto di unit test denominato "StringLibraryTest".
Fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni e selezionare Aggiungi>Nuovo progetto.
Nella pagina Aggiungi un nuovo progetto immettere mstest nella casella di ricerca. Scegliere C# o Visual Basic dall'elenco Linguaggio e quindi scegliere Tutte le piattaforme dall'elenco Piattaforma.
Scegliere il modello progetto di test MSTest e quindi scegliere Avanti.
Nella pagina Configura il nuovo progetto immettere StringLibraryTest nella casella Nome progetto. Scegliere quindi Avanti.
Nella pagina Informazioni aggiuntive selezionare .NET 6 (supporto a lungo termine) nella casella Framework. Scegli quindi Crea.
Visual Studio crea il progetto e apre il file di classe nella finestra del codice con il codice seguente. Se il linguaggio che si vuole usare non viene visualizzato, modificare il selettore di linguaggio nella parte superiore della pagina.
using Microsoft.VisualStudio.TestTools.UnitTesting; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Sub TestSub() End Sub End Class End Namespace
Il codice sorgente creato dal modello di unit test esegue le operazioni seguenti:
- Importa lo spazio dei nomi Microsoft.VisualStudio.TestTools.UnitTesting, contenente i tipi usati per il testing unità.
- Applica l'attributo TestClassAttribute alla classe
UnitTest1
. - Applica l'attributo TestMethodAttribute per definire
TestMethod1
in C# oTestSub
in Visual Basic.
Ogni metodo contrassegnato con [TestMethod] in una classe di test contrassegnata con [TestClass] viene eseguito automaticamente quando viene eseguito lo unit test.
Aggiungere un riferimento al progetto
Affinché il progetto di test funzioni con la classe StringLibrary
, aggiungere un riferimento nel progetto StringLibraryTest al progetto StringLibrary
.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Dipendenze del progetto StringLibraryTest e selezionare Aggiungi riferimento al progetto dal menu di scelta rapida.
Nella finestra di dialogo Gestione riferimenti espandere il nodo Progetti e selezionare la casella accanto a StringLibrary. L'aggiunta di un riferimento all'assembly
StringLibrary
consente al compilatore di trovare i metodi StringLibrary durante la compilazione del progetto StringLibraryTest.Seleziona OK.
Aggiungere ed eseguire metodi di unit test
Quando Visual Studio esegue uno unit test, esegue ogni metodo contrassegnato con l'attributo TestMethodAttribute in una classe contrassegnata con l'attributo TestClassAttribute. Un metodo di test termina quando viene trovato il primo errore o quando tutti i test contenuti nel metodo hanno avuto esito positivo.
I test più comuni chiamano i membri della classe Assert. Molti metodi assert includono almeno due parametri, uno dei quali corrisponde al risultato previsto del test, mentre l'altro corrisponde al risultato effettivo. Nella tabella seguente sono illustrati alcuni metodi chiamati più frequentemente della classe Assert
:
Metodi Assert | Funzione |
---|---|
Assert.AreEqual |
Verifica che due oggetti o valori siano uguali. L'asserzione ha esito negativo se i valori o gli oggetti non sono uguali. |
Assert.AreSame |
Verifica che due variabili oggetto facciano riferimento allo stesso oggetto. Il metodo ha esito negativo se le variabili fanno riferimento a oggetti diversi. |
Assert.IsFalse |
Verifica che una condizione sia false . Il metodo ha esito negativo se la condizione è true . |
Assert.IsNotNull |
Verifica che un oggetto non sia null . Il metodo ha esito negativo se l'oggetto è null . |
È anche possibile usare il metodo Assert.ThrowsException in un metodo di test per indicare il tipo di eccezione che dovrebbe generare. Il test ha esito negativo se l'eccezione specificata non viene generata.
Durante il test del metodo StringLibrary.StartsWithUpper
, è possibile specificare alcune stringhe che iniziano con un carattere maiuscolo. In tal caso si prevede che il metodo restituisca true
, quindi è possibile chiamare il metodo Assert.IsTrue. Analogamente, è possibile specificare alcune stringhe che iniziano con un valore diverso da un carattere maiuscolo. In tal caso si prevede che il metodo restituisca false
, quindi è possibile chiamare il metodo Assert.IsFalse.
Poiché il metodo di libreria gestisce le stringhe, è anche necessario assicurarsi che gestisca correttamente una stringa vuota (String.Empty
), una stringa valida senza caratteri e il cui Length è 0 e una stringa null
che non è stata inizializzata. È possibile chiamare StartsWithUpper
direttamente come metodo statico e passare un singolo argomento String. In alternativa, è possibile chiamare StartsWithUpper
come metodo di estensione in una variabile di string
assegnata a null
.
Verranno definiti tre metodi, ognuno dei quali chiama un metodo Assert per ogni elemento in una matrice di stringhe. Verrà chiamato un overload del metodo che consente di specificare un messaggio di errore da visualizzare in caso di errore del test. Il messaggio identifica la stringa che ha causato l'errore.
Per creare i metodi di test:
Nella finestra del codice UnitTest1.cs o UnitTest1.vb sostituire il codice con il codice seguente:
using Microsoft.VisualStudio.TestTools.UnitTesting; using UtilityLibraries; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestStartsWithUpper() { // Tests that we expect to return true. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsTrue(result, string.Format("Expected for '{0}': true; Actual: {1}", word, result)); } } [TestMethod] public void TestDoesNotStartWithUpper() { // Tests that we expect to return false. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word, result)); } } [TestMethod] public void DirectCallWithNullOrEmpty() { // Tests that we expect to return false. string?[] words = { string.Empty, null }; foreach (var word in words) { bool result = StringLibrary.StartsWithUpper(word); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word == null ? "<null>" : word, result)); } } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports UtilityLibraries Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Public Sub TestStartsWithUpper() ' Tests that we expect to return true. Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}") Next End Sub <TestMethod> Public Sub TestDoesNotStartWithUpper() ' Tests that we expect to return false. Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " "} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}") Next End Sub <TestMethod> Public Sub DirectCallWithNullOrEmpty() ' Tests that we expect to return false. Dim words() As String = {String.Empty, Nothing} For Each word In words Dim result As Boolean = StringLibrary.StartsWithUpper(word) Assert.IsFalse(result, $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}") Next End Sub End Class End Namespace
Il test dei caratteri maiuscoli nel metodo
TestStartsWithUpper
include la lettera maiuscola greca alfa (U+0391) e la lettera maiuscola cirillico EM (U+041C). Il test dei caratteri minuscoli nel metodoTestDoesNotStartWithUpper
include la lettera minuscola greca alfa (U+03B1) e la lettera minuscola cirillico Ghe (U+0433).Nella barra dei menu selezionare File>Salva UnitTest1.cs con nome o File>Salva UnitTest1.vb con nome. Nella finestra di dialogo Salva file con nome selezionare la freccia accanto al pulsante Salva e selezionare Salva con codifica.
Nella finestra di dialogo Conferma Salva con nome selezionare il pulsante Sì per salvare il file.
Nella finestra di dialogo Opzioni di salvataggio avanzate selezionare Unicode (UTF-8 con firma digitale) - Tabella codici 65001 dall'elenco a discesa Codifica e selezionare OK.
Se il salvataggio del codice sorgente come file con codifica UTF8 ha esito negativo, Visual Studio può salvarlo come file ASCII. In questo caso, il runtime non decodifica accuratamente i caratteri UTF8 all'esterno dell'intervallo ASCII e i risultati del test non saranno corretti.
Nella barra dei menu selezionare Test>Esegui tutti i test. Se la finestra Esplora test non viene aperta, aprirla scegliendo Test>Esplora test. I tre test sono elencati nella sezione Test superati e nella sezione Riepilogo è riportato il risultato dell'esecuzione dei test.
Gestire gli errori di test
Se si esegue lo sviluppo basato su test (TDD), si scrivono prima i test e non riescono la prima volta che vengono eseguiti. Aggiungere quindi il codice all'app che rende il test riuscito. Per questa esercitazione è stato creato il test dopo aver scritto il codice dell'app convalidato, in modo da non aver visto l'esito negativo del test. Per verificare che un test non riesca quando si prevede che non riesca, aggiungere un valore non valido all'input di test.
Modificare la matrice
words
del metodoTestDoesNotStartWithUpper
per includere la stringa "Error". Non è necessario salvare il file perché Visual Studio salva i file aperti automaticamente quando viene creata una soluzione per eseguire i test.string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " };
Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }
Eseguire il test selezionando Test>Esegui tutti i test dalla barra dei menu. La finestra Esplora test indica che due test hanno avuto esito positivo e uno esito negativo.
Selezionare il test non riuscito,
TestDoesNotStartWith
.Nella finestra Esplora test viene visualizzato il messaggio generato dal metodo Assert: "Assert.IsFalse failed. Expected for 'Error': false; actual: True". A causa dell'errore, non sono state testate stringhe nella matrice dopo il test di "Error".
Rimuovere la stringa "Errore" aggiunta nel passaggio 1. Eseguire nuovamente il test. I test verranno superati.
Test della versione di rilascio della libreria
Ora che tutti i test sono stati superati durante l'esecuzione della compilazione Debug della libreria, eseguire i test un tempo aggiuntivo rispetto alla versione di rilascio della libreria. Esistono infatti alcuni fattori, ad esempio le ottimizzazioni del compilatore, in grado di generare a volte comportamenti diversi tra la versione di debug e quella di rilascio.
Per testare la versione di rilascio, seguire questa procedura:
Nella barra degli strumenti di Visual Studio modificare la configurazione di compilazione da Debug a Rilascio.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto StringLibrary e selezionare Compila dal menu di scelta rapida per ricompilare la libreria.
Eseguire gli unit test scegliendo Test>Esegui tutti i test dalla barra dei menu. I test avranno esito positivo.
Esecuzione del debug dei test
Se si usa Visual Studio come IDE, è possibile usare lo stesso processo illustrato in Esercitazione: Eseguire il debug di un'applicazione console .NET usando Visual Studio per eseguire il debug del codice usando il progetto di unit test. Invece di avviare il progetto di app ShowCase, fare clic con il pulsante destro del mouse sul progetto StringLibraryTests e scegliere Debug test dal menu di scelta rapida.
Visual Studio avvia il progetto di test con il debugger collegato. L'esecuzione verrà arrestata in qualsiasi punto di interruzione aggiunto al progetto di test o al codice della libreria sottostante.
Risorse aggiuntive
Passaggi successivi
In questa esercitazione è stata testata una libreria di classi. È possibile rendere disponibile la libreria ad altri utenti pubblicandola in NuGet come pacchetto. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Se si pubblica una libreria come pacchetto NuGet, altri utenti possono installarla e usarla. Per informazioni su come farlo, seguire un'esercitazione su NuGet:
Non è necessario distribuire una libreria come pacchetto. Può essere incluso in un'app console che la usa. Per informazioni su come pubblicare un'app console, vedere l'esercitazione precedente in questa serie: