Condividi tramite


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

Creare un progetto di unit test

Gli unit test forniscono test software automatizzati durante lo sviluppo e la pubblicazione. MSTest è uno dei tre framework di test tra cui è possibile scegliere. Gli altri sono xUnit e nUnit .

  1. Avvia Visual Studio.

  2. Aprire la soluzione ClassLibraryProjects creata in Creare una libreria di classi .NET usando Visual Studio.

  3. Aggiungere alla soluzione un nuovo progetto di unit test denominato "StringLibraryTest".

    1. Fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni e selezionare AggiungiNuovo progetto.

    2. 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.

    3. Scegliere il modello progetto di test MSTest e quindi scegliere Avanti.

    4. Nella pagina Configura il nuovo progetto, immettere StringLibraryTest nella casella Nome progetto. Scegliere quindi Avanti.

    5. Nella pagina Informazioni aggiuntive, selezionare .NET 8 nella casella Framework. Scegliere quindi Crea.

  4. Visual Studio crea il progetto e apre il file di classe nella finestra del codice con il codice seguente. Se la lingua da usare non viene visualizzata, modificare il selettore di lingua 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:

    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 di StringLibrary.

  1. In Esplora soluzioni, fare clic con il pulsante destro del mouse sul nodo Dipendenze del progetto StringLibraryTest e scegliere Aggiungi riferimento al progetto dal menu di scelta rapida.

  2. Nella finestra di dialogo Gestione riferimenti , espandere il nodo Progetti di e selezionare la casella accanto a StringLibrary. L'aggiunta di un riferimento all'assembly StringLibrary consente al compilatore di trovare i metodi della StringLibrary durante la compilazione del progetto StringLibraryTest.

  3. Selezionare 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 è il risultato previsto del test e l'altro dei quali è il risultato effettivo del test. Nella tabella seguente sono illustrati alcuni dei metodi chiamati più frequentemente della classe Assert:

Metodi di asserzione Funzione
Assert.AreEqual Verifica che due valori o oggetti 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. L'asserzione ha esito negativo se le variabili fanno riferimento a oggetti diversi.
Assert.IsFalse Verifica che una condizione sia false. L'asserzione ha esito negativo se la condizione è true.
Assert.IsNotNull Verifica che un oggetto non sia null. L'asserzione ha esito negativo se l'oggetto è null.

È anche possibile usare il metodo Assert.ThrowsException (o Assert.Throws e Assert.ThrowsExactly se si usa MSTest 3.8 e versioni successive) 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 sollevata.

Nel test del metodo StringLibrary.StartsWithUpper si desidera specificare una serie di stringhe che iniziano con un carattere maiuscolo. Si prevede che il metodo restituisca true in questi casi, in modo da poter chiamare il metodo Assert.IsTrue. Analogamente, si vuole fornire una serie di stringhe che iniziano con un carattere diverso da un carattere maiuscolo. Si prevede che il metodo restituisca false in questi casi, in modo da poter 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 su una variabile string assegnata a null.

Verranno definiti tre metodi, ognuno dei quali chiama un metodo Assert per ogni elemento in una matrice di stringhe. Chiamerai un overload del metodo che ti 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:

  1. Nella finestra di codice di UnitTest1.cs o UnitTest1.vb, sostituisci il testo 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 metodo TestDoesNotStartWithUpper include la lettera minuscola greca alfa (U+03B1) e la lettera minuscola cirillico Ghe (U+0433).

  2. 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.

    finestra di dialogo Salva file con nome di Visual Studio

  3. Nella finestra di dialogo Conferma salvataggio con nome, selezionare il pulsante per salvare il file.

  4. Nella finestra di dialogo opzioni di salvataggio avanzate selezionare Unicode (UTF-8 con firma) - Codepage 65001 dall'elenco a discesa codifica e selezionare OK.

    finestra di dialogo Opzioni di salvataggio avanzate di Visual Studio

    Se non si salva il codice sorgente come file con codifica UTF8, 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.

  5. Nella barra dei menu selezionare Test>Esegui tutti i test. Se la finestra esplora test di non viene aperta, aprirla scegliendo TestEsplora test. I tre test sono elencati nella sezione test superati e la sezione Riepilogo segnala il risultato dell'esecuzione del test.

    finestra Esplora test con test superati

Gestire gli errori di test

Se si esegue lo sviluppo basato su test (TDD), si scrivono prima i test e falliscono quando vengono eseguiti per la prima volta. Quindi aggiungi il codice all'app per far sì che il test abbia successo. Per questa esercitazione, hai creato il test dopo aver scritto il codice dell'app che deve convalidare, quindi non hai visto il test fallire. Per verificare che un test non riesca quando si prevede che non riesca, aggiungere un valore non valido all'input di test.

  1. Modificare la matrice di words nel metodo TestDoesNotStartWithUpper per includere la stringa "Error". Non è necessario salvare il file perché Visual Studio salva automaticamente i file aperti quando una soluzione viene compilata per eseguire i test.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Eseguire il test selezionando Test>Esegui tutti i test dalla barra dei menu. La finestra Test Explorer indica che due test hanno avuto risultato positivo e uno è fallito.

    finestra Esplora test con test non superati

  3. Selezionare il test non riuscito TestDoesNotStartWith.

    Nella finestra Esplora Test viene visualizzato il messaggio generato dall'asserzione: "Assert.IsFalse failed. Previsto per 'Error': false; effettivo: vero". A causa dell'errore, nessuna stringa nell'array dopo "Error" è stata testata.

    finestra

  4. Rimuovere la stringa "Errore" aggiunta nel passaggio 1. Ripeti il test e i test vengono superati.

Testare la versione release della libreria

Ora che tutti i test sono stati superati durante l'esecuzione della build Debug della libreria, eseguire i test un'ulteriore volta nella build Release della libreria. Alcuni fattori, incluse le ottimizzazioni del compilatore, possono talvolta produrre un comportamento diverso tra compilazioni di debug e rilascio.

Per testare la build di rilascio:

  1. Nella barra degli strumenti di Visual Studio modificare la configurazione della build da Debug a Release.

    barra degli strumenti di Visual Studio con versione di release evidenziata

  2. In Esplora soluzioni, fare clic con il pulsante destro del mouse sul progetto StringLibrary e scegliere Compila dal menu di scelta rapida per ricompilare la libreria.

    menu contestuale StringLibrary con il comando di compilazione

  3. Esegui i test unitari scegliendo Test>Esegui tutti i test dalla barra dei menu. I test passano.

Eseguire il 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 dell'app ShowCase, fare clic con il pulsante destro del mouse sul progetto StringLibraryTests e scegliere Debug tests dal menu di scelta rapida.

Visual Studio avvia il progetto di test con il debugger collegato. L'esecuzione verrà arrestata in un punto di interruzione che hai aggiunto al progetto di test o al codice della libreria di base.

Risorse aggiuntive

Passaggi successivi

In questo tutorial, hai effettuato i test unitari su una libreria di classi. È possibile rendere disponibile la libreria ad altri utenti pubblicandola in NuGet come pacchetto. Per sapere come, segui un tutorial su NuGet:

Se si pubblica una libreria come pacchetto NuGet, altri utenti possono installarla e usarla. Per sapere come, segui un tutorial 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: