Procedura dettagliata: Sviluppo basato su test con Esplora test
Creare unit test per garantire il corretto funzionamento del codice attraverso modifiche incrementali. Esistono diversi framework che possono essere utilizzati per scrivere unit test, tra i quali alcuni sviluppati da terze parti. Alcuni framework di test sono specializzati per il testing in diversi linguaggi o piattaforme. Esplora test fornisce una singola interfaccia per gli unit test per uno qualsiasi di questi framework. Per altre informazioni su Esplora test, vedere Eseguire unit test con Esplora test e Domande frequenti su Esplora test.
Questa procedura dettagliata illustra come sviluppare un metodo testato in C# usando il framework di test Microsoft (MSTest). È possibile adattare facilmente la procedura per altri linguaggi o altri framework di test, ad esempio NUnit. Per altre informazioni, vedere Installare framework di unit test di terze parti.
Creare un test e generare codice
Creare un progetto libreria di classi C# per .NET o .NET Standard. Questo progetto conterrà il codice da testare. Assegnare al progetto il nome MyMath.
Nella stessa soluzione aggiungere un nuovo progetto di test MSTest per .NET.
In Visual Studio 2019 versione 16.9 il nome del modello di progetto MSTest è Progetto unit test.
Assegnare al progetto di test il nome MathTests.
Scrivere un metodo di test semplice che verifica il risultato ottenuto per un input specifico. Aggiungere il codice seguente alla classe
UnitTest1
:[TestMethod] public void BasicRooterTest() { // Create an instance to test: Rooter rooter = new Rooter(); // Define a test input and output value: double expectedResult = 2.0; double input = expectedResult * expectedResult; // Run the method under test: double actualResult = rooter.SquareRoot(input); // Verify the result: Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100); }
Generare un tipo dal codice di test.
Posizionare il cursore su
Rooter
, quindi dal menu Lampadina scegliere Genera il tipo 'Rooter'>Genera nuovo tipo.Nella finestra di dialogo Genera tipo impostare Progetto su MyMath, il progetto libreria di classi, e quindi scegliere OK.
Generare un metodo dal codice di test. Posizionare il cursore su
SquareRoot
e quindi dal menu Lampadina scegliere Genera il metodo 'Rooter.SquareRoot'.Eseguire lo unit test.
Aprire Esplora test.
Per aprire Esplora test dal menu Test , scegliere Esplora test.
Per aprire Esplora test dal menu Test scegliere Esplora test di Windows>.
In Esplora test fare clic sul pulsante Esegui tutto per eseguire il test.
La soluzione verrà compilata e il test verrà eseguito e avrà esito negativo.
Selezionare il nome del test.
I dettagli del test vengono visualizzati nel riquadro Riepilogo dettagli test.
Selezionare il collegamento superiore in Analisi dello stack per passare alla posizione in cui si è verificato l'errore nel test.
A questo punto sono stati creati un test e uno stub che è possibile modificare in modo che il test abbia esito positivo.
Verificare una modifica del codice
Nel file Class1.cs migliorare il codice di
SquareRoot
:public double SquareRoot(double input) { return input / 2; }
In Esplora test scegliere Esegui tutto.
La soluzione verrà compilata e il test verrà eseguito e avrà esito positivo.
Estendere l'intervallo degli input
Per migliorare le probabilità che il codice funzioni in tutti i casi, aggiungere test che usano una gamma più ampia di valori di input.
Suggerimento
Evitare di modificare i test esistenti che hanno avuto successo. Piuttosto, aggiungere nuovi test. Modificare i test esistenti solo in caso di variazione dei requisiti dell'utente. Questo criterio assicura che le funzionalità esistenti non vadano perse mentre si lavora per estendere il codice.
Nella classe di test aggiungere il test seguente, che usa un intervallo di valori di input:
[TestMethod] public void RooterValueRange() { // Create an instance to test. Rooter rooter = new Rooter(); // Try a range of values. for (double expected = 1e-8; expected < 1e+8; expected *= 3.2) { RooterOneValue(rooter, expected); } } private void RooterOneValue(Rooter rooter, double expectedResult) { double input = expectedResult * expectedResult; double actualResult = rooter.SquareRoot(input); Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000); }
In Esplora test scegliere Esegui tutto.
Il nuovo test ha esito negativo nonostante il primo test abbia comunque esito positivo. Per trovare il punto di errore, selezionare il test con esito negativo e quindi esaminare i dettagli nel riquadro Riepilogo dettagli test.
Controllare il metodo sottoposto al test per vedere quale potrebbe essere l'errore. Modificare il codice di
SquareRoot
come illustrato di seguito:public double SquareRoot(double input) { double result = input; double previousResult = -input; while (Math.Abs(previousResult - result) > result / 1000) { previousResult = result; result = result - (result * result - input) / (2 * result); } return result; }
In Esplora test scegliere Esegui tutto.
Ora entrambi i test avranno esito positivo.
Aggiungere test per i casi eccezionali
Aggiungere un nuovo test per gli input negativi:
[TestMethod] public void RooterTestNegativeInput() { Rooter rooter = new Rooter(); Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1)); }
In Esplora test scegliere Esegui tutto.
Il metodo sottoposto al test entra in un ciclo e deve essere annullato manualmente.
Scegliere Annulla sulla barra degli strumenti di Esplora test.
L'esecuzione del test viene interrotta.
Correggere il codice di
SquareRoot
aggiungendo l'istruzioneif
seguente all'inizio del metodo:public double SquareRoot(double input) { if (input <= 0.0) { throw new ArgumentOutOfRangeException(); } ...
In Esplora test scegliere Esegui tutto.
Tutti i test avranno esito positivo.
Effettuare il refactoring del codice sottoposto a test
Effettuare il refactoring del codice, ma non modificare i test.
Suggerimento
Un refactoring è una modifica finalizzata a migliorare le prestazioni del codice o a rendere il codice più facile da comprendere. Non è concepito per modificare il comportamento del codice e pertanto i test non vengono modificati.
Si consiglia di effettuare le operazioni di refactoring separatamente dai passaggi che estendono le funzionalità. Mantenendo i test invariati ci si assicura che non siano stati introdotti accidentalmente bug durante il refactoring.
Modificare la riga che calcola
result
nel metodoSquareRoot
come indicato di seguito:public double SquareRoot(double input) { if (input <= 0.0) { throw new ArgumentOutOfRangeException(); } double result = input; double previousResult = -input; while (Math.Abs(previousResult - result) > result / 1000) { previousResult = result; result = (result + input / result) / 2; //was: result = result - (result * result - input) / (2*result); } return result; }
Scegliere Esegui tutto e verificare che tutti i test abbiano ancora esito positivo.