Introduzione a C# e MSTest

Questa esercitazione illustra un'esperienza interattiva che crea una soluzione di esempio dettagliata per apprendere i concetti di unit test. Se preferisci seguire il tutorial usando una soluzione predefinita, visualizza o scarica il codice di esempio prima di iniziare. Per istruzioni sul download, vedere esempi ed esercitazioni .

Questo articolo descrive il test di un progetto .NET Core. Se si sta testando un progetto ASP.NET Core, vedere test di integrazione in ASP.NET Core.

Prerequisiti

  • La versione più recente .NET SDK
  • editor di Visual Studio Code
  • Il DevKit C#

Creare il progetto di origine

Aprire una finestra della shell. Creare una directory denominata unit-testing-using-mstest per contenere la soluzione. All'interno di questa nuova directory eseguire dotnet new sln per creare un nuovo file di soluzione per la libreria di classi e il progetto di test. Creare una directory PrimeService. La seguente struttura mostra la disposizione delle directory e dei file fino a questo punto.

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService

Imposta PrimeService come directory corrente ed esegui dotnet new classlib per creare il progetto sorgente.

Tornare alla directory unit-testing-using-mstest di nuovo. Eseguire dotnet sln add per aggiungere il progetto di libreria di classi alla soluzione:

dotnet sln add PrimeService/PrimeService.csproj

Rinominare Class1.cs nella PrimeService directory in PrimeService.cs. Sostituire il codice nel file con il codice seguente per creare un'implementazione non riuscita della PrimeService classe :

using System;

namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Creare il progetto di test

Creare la directory PrimeService.Tests . La seguente illustrazione mostra la struttura della directory:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

Impostare la directory PrimeService.Tests come directory corrente e creare un nuovo progetto usando dotnet new mstest. Il comando dotnet new crea un progetto di test che usa MSTest come libreria di test. Il modello configura il test runner nel file PrimeServiceTests.csproj :

<ItemGroup>
  <PackageReference Include="MSTest" Version="4.1.0" />
</ItemGroup>

Note

Le versioni del pacchetto illustrate sono esempi. Le versioni generate da dotnet new mstest dipendono da .NET SDK. I modelli e gli esempi scaricati potrebbero non usare le versioni più recenti del pacchetto NuGet.

Per verificare la disponibilità di aggiornamenti dopo aver creato ed eseguito i test, eseguire dotnet package list --outdated dalla directory del progetto di test. Usare dotnet package add <PACKAGE_NAME> per aggiornare un riferimento al pacchetto alla versione stabile compatibile più recente. Esaminare le note sulla versione per verificare le modifiche incompatibili prima dell'aggiornamento ed eseguire di nuovo dotnet test in seguito.

Se si usa .NET 9 SDK o versioni precedenti, usare dotnet list package --outdated edotnet add package <PACKAGE_NAME>.

Il progetto di test richiede altri pacchetti per creare ed eseguire unit test. dotnet new nel passaggio precedente sono stati aggiunti i pacchetti e gli strumenti MSTest necessari per la creazione di report di code coverage.

Aggiungere la libreria delle classi PrimeService come un'altra dipendenza al progetto. Usare il comando dotnet reference add:

dotnet reference add ../PrimeService/PrimeService.csproj

È possibile visualizzare l'intero file nel repository degli esempi su GitHub.

La struttura seguente illustra il layout finale della soluzione:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeServiceTests.csproj

Passare alla directory unit-testing-using-mstest ed eseguire dotnet sln add:

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Creare il primo test

Scrivere un test con esito negativo, passarlo, quindi ripetere il processo. Rimuovere UnitTest1.cs dalla directory PrimeService.Tests e creare un nuovo file C# denominato PrimeService_IsPrimeShould.cs con il contenuto seguente:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;

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

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

        [TestMethod]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            bool result = _primeService.IsPrime(1);

            Assert.IsFalse(result, "1 shouldn't be prime");
        }
    }
}

L'attributo TestClass indica una classe che contiene unit test. L'attributo TestMethod indica che un metodo è un metodo di test.

MSTest crea una nuova istanza della classe di test per ogni test, quindi il costruttore crea un'istanza separata di PrimeService per ogni test. Il costruttore contiene solo la configurazione necessaria per ogni test di questa classe. Se i test richiedono una configurazione diversa, creare oggetti nei metodi di test o chiamare metodi helper da tali metodi. Per indicazioni, vedere Usare metodi helper invece di Setup e Teardown.

Salvare questo file ed eseguire dotnet test per compilare i test e la libreria di classi e quindi eseguire i test. Lo strumento esecutore di test MSTest contiene il punto di ingresso del programma per eseguire i test. dotnet test avvia il test runner utilizzando il progetto di test unitario che hai creato.

Il test non riesce perché l'implementazione non è ancora stata creata. Eseguire questo test scrivendo il codice più semplice nella classe PrimeService che funziona:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Nella directory unit-testing-using-mstest eseguire dotnet test di nuovo. Il comando dotnet test esegue una compilazione per il progetto PrimeService e quindi per il progetto PrimeService.Tests. Dopo la compilazione di entrambi i progetti, viene eseguito questo singolo test. Passa.

Aggiungere altre funzionalità

Ora che hai superato un test, è il momento di scrivere altri test. Esistono alcuni altri semplici casi per i numeri primi: 0, -1. È possibile aggiungere nuovi test con l'attributo TestMethod, ma questo diventa noioso. Esistono altri attributi MSTest che consentono di scrivere un gruppo di test simili. Un metodo di test può eseguire lo stesso codice ma avere argomenti di input diversi. È possibile usare l'attributo DataRow per specificare i valori per tali input.

Anziché creare nuovi test, applicare questi due attributi per creare un singolo test basato sui dati. Il test basato sui dati è un metodo che testa diversi valori minori di due, ovvero il numero primo più basso. Aggiungere un nuovo metodo di test in PrimeService_IsPrimeShould.cs:

[TestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    bool result = _primeService.IsPrime(value);

    Assert.IsFalse(result, $"{value} should not be prime");
}

Esegui dotnet test e due di questi test falliscono. Per superare tutti i test, modificare la if clausola all'inizio del IsPrime metodo nel file PrimeService.cs :

if (candidate < 2)

Continuare a eseguire l'iterazione aggiungendo altri test, altre teorie e altro codice nella libreria principale. È stata completata la versione dei test e l'implementazione completa della libreria.

Hai costruito una piccola libreria e un set di unit test per quella libreria. La soluzione è stata strutturata in modo che l'aggiunta di nuovi pacchetti e test faccia parte del normale flusso di lavoro. La maggior parte del tempo e dello sforzo è stata concentrata sulla risoluzione degli obiettivi dell'applicazione.

Eseguire test in Azure Pipelines

Per eseguire automaticamente i test quando si esegue il push delle modifiche, aggiungere una configurazione Azure Pipelines al repository contenente la soluzione completata. È necessario un progetto Azure DevOps e l'accesso a un agente ospitato Microsoft. Per i prerequisiti, vedere Creare la prima pipeline.

  1. Nella radice del repository creare un azure-pipelines.yml file con il contenuto seguente. Nell'esempio si presuppone che le directory PrimeService e PrimeService.Tests si trovino nella radice del repository e che entrambi i progetti siano destinati a .NET 10.

    trigger:
    - main
    
    pool:
      vmImage: ubuntu-latest
    
    steps:
    - task: UseDotNet@2
      displayName: Install .NET SDK
      inputs:
        packageType: sdk
        version: 10.0.x
    
    - task: DotNetCoreCLI@2
      displayName: Run MSTest tests
      inputs:
        command: test
        projects: PrimeService.Tests/PrimeService.Tests.csproj
        arguments: --configuration Release
        publishTestResults: true
    
  2. Modificare la configurazione in modo che corrisponda al repository:

    • Se il ramo ha un nome diverso, sostituire main in trigger con il nome del ramo.
    • Se la soluzione si trova in una sottodirectory, aggiorna projects impostandolo sul percorso del progetto di test relativo alla radice del repository.
    • Se i progetti hanno come destinazione una versione diversa di .NET, modificare version nell'attività UseDotNet@2 in modo che corrisponda. Ad esempio, usare 8.0.x per i progetti destinati a net8.0. Se il repository contiene un global.json file, assicurarsi che l'SDK installato soddisfi i requisiti di versione.
  3. Eseguire il commit e il push della soluzione e del file azure-pipelines.yml nel repository Git.

  4. Nel progetto Azure DevOps selezionare Pipelines>nuova pipeline o Crea pipeline se si tratta della prima pipeline. Selezionare il provider del repository e il repository.

  5. Nella pagina Configura la pipeline selezionare file YAML di Azure Pipelines esistente, selezionare il ramo e /azure-pipelines.yml quindi selezionare Continua. Esaminare la configurazione e selezionare Esegui.

L'attività UseDotNet@2task installa .NET SDK. L'attività DotNetCoreCLI@2 task esegue dotnet test, che ripristina le dipendenze, compila il progetto di test e la relativa libreria a cui si fa riferimento ed esegue i test nella configurazione release.

Con publishTestResults: true, l'attività genera un file di risultati TRX e pubblica i risultati, anche se un test non riesce. Dopo l'esecuzione, aprire la scheda Test dell'esecuzione della pipeline per esaminare i test superati e non superati. Un test non riuscito causa anche l'esito negativo dell'attività di test e della pipeline.

Note

Questo esempio usa la configurazione VSTest predefinita da dotnet new mstest con .NET 10 SDK. Se si abilita Microsoft.Testing.Platform (MTP), vedere Eseguire test MTP nell'integrazione continua per la configurazione dello strumento di esecuzione necessaria.

Vedere anche