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

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

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

    New code and test projects

    New code and test projects

  3. 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);
    }
    
  4. Generare un tipo dal codice di test.

    1. Posizionare il cursore su Rooter, quindi dal menu Lampadina scegliere Genera il tipo 'Rooter'>Genera nuovo tipo.

      Generate new type quick action

      Generate new type quick action

    2. Nella finestra di dialogo Genera tipo impostare Progetto su MyMath, il progetto libreria di classi, e quindi scegliere OK.

      Generate Type dialog box in Visual Studio 2019

      Generate Type dialog box in Visual Studio 2019

  5. Generare un metodo dal codice di test. Posizionare il cursore su SquareRoot e quindi dal menu Lampadina scegliere Genera il metodo 'Rooter.SquareRoot'.

  6. Eseguire lo unit test.

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

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

  7. Selezionare il nome del test.

    I dettagli del test vengono visualizzati nel riquadro Riepilogo dettagli test.

    Test Detail Summary in Test Explorer

    Test Detail Summary in Test Explorer

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

  1. Nel file Class1.cs migliorare il codice di SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. In Esplora test scegliere Esegui tutto.

    La soluzione verrà compilata e il test verrà eseguito e avrà esito positivo.

    Test Explorer showing a passing test

    Test Explorer showing a passing test

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.

  1. 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);
    }
    
  2. 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.

  3. 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;
    }
    
  4. In Esplora test scegliere Esegui tutto.

    Ora entrambi i test avranno esito positivo.

Aggiungere test per i casi eccezionali

  1. Aggiungere un nuovo test per gli input negativi:

    [TestMethod]
    public void RooterTestNegativeInput()
    {
        Rooter rooter = new Rooter();
        Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
    }
    
  2. In Esplora test scegliere Esegui tutto.

    Il metodo sottoposto al test entra in un ciclo e deve essere annullato manualmente.

  3. Scegliere Annulla sulla barra degli strumenti di Esplora test.

    L'esecuzione del test viene interrotta.

  4. Correggere il codice di SquareRoot aggiungendo l'istruzione if seguente all'inizio del metodo:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  5. 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.

  1. Modificare la riga che calcola result nel metodo SquareRoot 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;
    }
    
  2. Scegliere Esegui tutto e verificare che tutti i test abbiano ancora esito positivo.

    Test Explorer showing 3 passed tests

    Test Explorer showing 3 passed tests