Testing unità di C# in .NET Core usando il test dotnet e xUnitUnit testing C# in .NET Core using dotnet test and xUnit

Questa esercitazione illustra come compilare una soluzione contenente un progetto unit test e un progetto di codice sorgente.This tutorial shows how to build a solution containing a unit test project and source code project. Per seguire l'esercitazione usando una soluzione predefinita, visualizzare o scaricare il codice di esempio.To follow the tutorial using a pre-built solution, view or download the sample code. Per istruzioni sul download, vedere Esempi ed esercitazioni.For download instructions, see Samples and Tutorials.

Creare la soluzioneCreate the solution

In questa sezione viene creata una soluzione che contiene i progetti di origine e di test.In this section, a solution is created that contains the source and test projects. La soluzione completa presenta la struttura di directory seguente:The completed solution has the following directory structure:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.cs
        PrimeService.csproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.cs
        PrimeServiceTests.csproj

Le istruzioni seguenti forniscono i passaggi per creare la soluzione di test.The following instructions provide the steps to create the test solution. Per istruzioni su come creare la soluzione di test in un unico passaggio, vedere comandi per creare una soluzione di test .See Commands to create test solution for instructions to create the test solution in one step.

  • Aprire una finestra della shell.Open a shell window.

  • Eseguire il comando seguente:Run the following command:

    dotnet new sln -o unit-testing-using-dotnet-test
    

    Il comando dotnet new sln crea una nuova soluzione nella directory unit-testing-using-DotNet-test .The dotnet new sln command creates a new solution in the unit-testing-using-dotnet-test directory.

  • Passare alla cartella unit-testing-using-DotNet-test .Change directory to the unit-testing-using-dotnet-test folder.

  • Eseguire il comando seguente:Run the following command:

    dotnet new classlib -o PrimeService
    

    Il dotnet new classlib comando crea un nuovo progetto di libreria di classi nella cartella PrimeService .The dotnet new classlib command creates a new class library project in the PrimeService folder. La nuova libreria di classi conterrà il codice da testare.The new class library will contain the code to be tested.

  • Assegnare il nome PrimeService.cs al file Class1.cs.Rename Class1.cs to PrimeService.cs.

  • Sostituire il codice in PrimeService.cs con il codice seguente:Replace the code in PrimeService.cs with the following code:

      using System;
    
      namespace Prime.Services
      {
          public class PrimeService
          {
              public bool IsPrime(int candidate)
              {
                  throw new NotImplementedException("Not implemented.");
              }
          }
      }
    
  • Il codice precedente:The preceding code:

    • Genera un NotImplementedException con un messaggio che indica che non è implementato.Throws a NotImplementedException with a message indicating it's not implemented.
    • Viene aggiornato più avanti nell'esercitazione.Is updated later in the tutorial.
  • Nella directory unit-testing-using-DotNet-test eseguire il comando seguente per aggiungere il progetto di libreria di classi alla soluzione:In the unit-testing-using-dotnet-test directory, run the following command to add the class library project to the solution:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Creare il progetto PrimeService. tests eseguendo il comando seguente:Create the PrimeService.Tests project by running the following command:

    dotnet new xunit -o PrimeService.Tests
    
  • Il comando precedente:The preceding command:

    • Crea il progetto PrimeService. tests nella directory PrimeService. tests .Creates the PrimeService.Tests project in the PrimeService.Tests directory. Il progetto di test USA xUnit come libreria di test.The test project uses xUnit as the test library.
    • Configura il test runner aggiungendo gli elementi <PackageReference />seguenti al file di progetto:Configures the test runner by adding the following <PackageReference />elements to the project file:
      • "Microsoft. NET. test. SDK""Microsoft.NET.Test.Sdk"
      • xUnit"xunit"
      • "xUnit. Runner. VisualStudio""xunit.runner.visualstudio"
  • Aggiungere il progetto di test al file di soluzione eseguendo il comando seguente:Add the test project to the solution file by running the following command:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Aggiungere la libreria di classi PrimeService come dipendenza al progetto PrimeService. tests :Add the PrimeService class library as a dependency to the PrimeService.Tests project:

    dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj  
    

Comandi per creare la soluzioneCommands to create the solution

In questa sezione vengono riepilogati tutti i comandi della sezione precedente.This section summarizes all the commands in the previous section. Ignorare questa sezione se è stata completata la procedura descritta nella sezione precedente.Skip this section if you've completed the steps in the previous section.

I comandi seguenti creano la soluzione di test in un computer Windows.The following commands create the test solution on a windows machine. Per macOS e UNIX, aggiornare il comando ren alla versione del sistema operativo di ren per rinominare un file:For macOS and Unix, update the ren command to the OS version of ren to rename a file:

dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Seguire le istruzioni per "sostituire il codice in PrimeService.cs con il codice seguente" nella sezione precedente.Follow the instructions for "Replace the code in PrimeService.cs with the following code" in the previous section.

Creare un testCreate a test

Un approccio comune nello sviluppo basato su test (TDD) consiste nel scrivere un test prima di implementare il codice di destinazione.A popular approach in test driven development (TDD) is to write a test before implementing the target code. Questa esercitazione usa l'approccio TDD.This tutorial uses the TDD approach. Il metodo IsPrime è chiamabile, ma non è implementato.The IsPrime method is callable, but not implemented. Una chiamata di test a IsPrime ha esito negativo.A test call to IsPrime fails. Con TDD, viene scritto un test noto come non riuscito.With TDD, a test is written that is known to fail. Il codice di destinazione viene aggiornato per fare in modo che il test venga superato.The target code is updated to make the test pass. Si continua a ripetere questo approccio, scrivendo un test con esito negativo e quindi aggiornando il codice di destinazione da passare.You keep repeating this approach, writing a failing test and then updating the target code to pass.

Aggiornare il progetto PrimeService. tests :Update the PrimeService.Tests project:

  • Eliminare PrimeService. tests/UnitTest1. cs.Delete PrimeService.Tests/UnitTest1.cs.
  • Creare un file PrimeService. tests/PrimeService_IsPrimeShould. cs .Create a PrimeService.Tests/PrimeService_IsPrimeShould.cs file.
  • Sostituire il codice in PrimeService_IsPrimeShould. cs con il codice seguente:Replace the code in PrimeService_IsPrimeShould.cs with the following code:
using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    public class PrimeService_IsPrimeShould
    {
        private readonly PrimeService _primeService;

        public PrimeService_IsPrimeShould()
        {
            _primeService = new PrimeService();
        }

        [Fact]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.False(result, "1 should not be prime");
        }
    }
}

L'attributo [Fact] dichiara un metodo di test eseguito dal test runner.The [Fact] attribute declares a test method that's run by the test runner. Dalla cartella PrimeService. tests eseguire dotnet test.From the PrimeService.Tests folder, run dotnet test. Il comando DotNet test Compila entrambi i progetti ed esegue i test.The dotnet test command builds both projects and runs the tests. XUnit Test Runner contiene il punto di ingresso del programma per eseguire i test.The xUnit test runner contains the program entry point to run the tests. dotnet test avvia il test runner utilizzando il progetto unit test.dotnet test starts the test runner using the unit test project.

Il test ha esito negativo perché IsPrime non è stato implementato.The test fails because IsPrime hasn't been implemented. Utilizzando l'approccio TDD, scrivere solo codice sufficiente per consentire il superamento del test.Using the TDD approach, write only enough code so this test passes. Aggiornare IsPrime con il codice seguente:Update IsPrime with the following code:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Eseguire dotnet test.Run dotnet test. Il test ha esito positivo.The test passes.

Aggiungi altri testAdd more tests

Aggiungere i test dei numeri primi per 0 e-1.Add prime number tests for 0 and -1. È possibile copiare il test precedente e modificare il codice seguente per usare 0 e-1:You could copy the preceding test and change the following code to use 0 and -1:

var result = _primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");

La copia del codice di test quando solo un parametro cambia causa la duplicazione del codice e il sovraccarico dei test.Copying test code when only a parameter changes results in code duplication and test bloat. Gli attributi xUnit seguenti consentono di scrivere una suite di test simili:The following xUnit attributes enable writing a suite of similar tests:

  • [Theory] rappresenta una suite di test che eseguono lo stesso codice, ma hanno argomenti di input diversi.[Theory] represents a suite of tests that execute the same code but have different input arguments.

  • L'attributo [InlineData] specifica i valori per tali input.[InlineData] attribute specifies values for those inputs.

Anziché creare nuovi test, applicare gli attributi xUnit precedenti per creare una singola teoria.Rather than creating new tests, apply the preceding xUnit attributes to create a single theory. Sostituire il codice seguente:Replace the following code:

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
    var result = _primeService.IsPrime(1);

    Assert.False(result, "1 should not be prime");
}

con il codice seguente:with the following code:

[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);
    
    Assert.False(result, $"{value} should not be prime");
}

Nel codice precedente [Theory] e [InlineData] abilitano il testing di diversi valori minori di due.In the preceding code, [Theory] and [InlineData] enable testing several values less than two. Due è il numero primo più piccolo.Two is the smallest prime number.

Eseguire dotnet test, due dei test hanno esito negativo.Run dotnet test, two of the tests fail. Per far passare tutti i test, aggiornare il metodo IsPrime con il codice seguente:To make all of the tests pass, update the IsPrime method with the following code:

public bool IsPrime(int candidate)
{
    if (candidate < 2)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Seguendo l'approccio di TDD, aggiungere altri test non superati, quindi aggiornare il codice di destinazione.Following the TDD approach, add more failing tests, then update the target code. Vedere la versione completa dei test e l' implementazione completa della libreria.See the finished version of the tests and the complete implementation of the library.

Il metodo di IsPrime completato non è un algoritmo efficiente per il test di primalità.The completed IsPrime method is not an efficient algorithm for testing primality.

Risorse aggiuntiveAdditional resources