C# de teste de unidade no .NET Core usando dotnet test e xUnitUnit testing C# in .NET Core using dotnet test and xUnit

Este tutorial mostra como construir uma solução contendo um projeto de teste de unidade e projeto de código fonte.This tutorial shows how to build a solution containing a unit test project and source code project. Para seguir o tutorial usando uma solução pré-construída, visualize ou baixe o código de amostra.To follow the tutorial using a pre-built solution, view or download the sample code. Para obter instruções de download, consulte Exemplos e tutoriais.For download instructions, see Samples and Tutorials.

Criar a soluçãoCreate the solution

Nesta seção, é criada uma solução que contém a origem e os projetos de teste.In this section, a solution is created that contains the source and test projects. A solução concluída tem a seguinte estrutura de diretório: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

As instruções a seguir fornecem as etapas para criar a solução de teste.The following instructions provide the steps to create the test solution. Consulte Comandos para criar a solução de teste para obter instruções para criar a solução de teste em uma etapa.See Commands to create test solution for instructions to create the test solution in one step.

  • Abra uma janela do shell.Open a shell window.

  • Execute o comando a seguir:Run the following command:

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

    O dotnet new sln comando cria uma nova solução no diretório de teste de teste de unidade-dotnet-test.The dotnet new sln command creates a new solution in the unit-testing-using-dotnet-test directory.

  • Alterar o diretório para a pasta de teste de unidade-usando-dotnet-test.Change directory to the unit-testing-using-dotnet-test folder.

  • Execute o comando a seguir:Run the following command:

    dotnet new classlib -o PrimeService
    

    O dotnet new classlib comando cria um novo projeto de biblioteca de classes na pasta PrimeService.The dotnet new classlib command creates a new class library project in the PrimeService folder. A nova biblioteca de classe conterá o código a ser testado.The new class library will contain the code to be tested.

  • Renomeie Class1.cs como PrimeService.cs.Rename Class1.cs to PrimeService.cs.

  • Substitua o código em PrimeService.cs pelo seguinte código: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.");
              }
          }
      }
    
  • O código anterior:The preceding code:

    • Joga NotImplementedException um com uma mensagem indicando que não foi implementado.Throws a NotImplementedException with a message indicating it's not implemented.
    • É atualizado mais tarde no tutorial.Is updated later in the tutorial.
  • No diretório de teste de unidade-usando-dotnet-test, execute o seguinte comando para adicionar o projeto da biblioteca de classe à solução: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
    
  • Crie o projeto PrimeService.Tests executando o seguinte comando:Create the PrimeService.Tests project by running the following command:

    dotnet new xunit -o PrimeService.Tests
    
  • O comando anterior:The preceding command:

    • Cria o projeto PrimeService.Tests no diretório PrimeService.Tests.Creates the PrimeService.Tests project in the PrimeService.Tests directory. O projeto de teste usa xUnit como biblioteca de testes.The test project uses xUnit as the test library.
    • Configura o corredor de teste <PackageReference />adicionando os seguintes elementos ao arquivo do projeto: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"
  • Adicione o projeto de teste ao arquivo da solução executando o seguinte comando:Add the test project to the solution file by running the following command:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Adicione PrimeService a biblioteca de classes como uma dependência ao projeto 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  
    

Comandos para criar a soluçãoCommands to create the solution

Esta seção resume todos os comandos da seção anterior.This section summarizes all the commands in the previous section. Pule esta seção se você tiver concluído as etapas na seção anterior.Skip this section if you've completed the steps in the previous section.

Os comandos a seguir criam a solução de teste em uma máquina windows.The following commands create the test solution on a windows machine. Para macOS e Unix, atualize ren o ren comando para a versão do Sistema Operacional para renomear um arquivo: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

Siga as instruções de "Substituir o código em PrimeService.cs com o seguinte código" na seção anterior.Follow the instructions for "Replace the code in PrimeService.cs with the following code" in the previous section.

Crie um testeCreate a test

Uma abordagem popular no desenvolvimento baseado em teste (TDD) é escrever um teste antes de implementar o código de destino.A popular approach in test driven development (TDD) is to write a test before implementing the target code. Este tutorial usa a abordagem TDD.This tutorial uses the TDD approach. O IsPrime método é calável, mas não implementado.The IsPrime method is callable, but not implemented. Uma chamada IsPrime de teste para falhar.A test call to IsPrime fails. Com TDD, um teste é escrito que é conhecido por falhar.With TDD, a test is written that is known to fail. O código de destino é atualizado para fazer o teste passar.The target code is updated to make the test pass. Você continua repetindo essa abordagem, escrevendo um teste de falha e atualizando o código de destino para passar.You keep repeating this approach, writing a failing test and then updating the target code to pass.

Atualize o projeto PrimeService.Tests:Update the PrimeService.Tests project:

  • Exclua PrimeService.Tests/UnitTest1.cs.Delete PrimeService.Tests/UnitTest1.cs.
  • Crie um arquivo PrimeService.Tests/PrimeService_IsPrimeShould.cs.Create a PrimeService.Tests/PrimeService_IsPrimeShould.cs file.
  • Substitua o código em PrimeService_IsPrimeShould.cs com o seguinte código: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");
        }
    }
}

O [Fact] atributo declara um método de teste que é executado pelo corredor de teste.The [Fact] attribute declares a test method that's run by the test runner. A partir da pasta PrimeService.Tests, execute dotnet test.From the PrimeService.Tests folder, run dotnet test. O comando de teste dotnet constrói ambos os projetos e executa os testes.The dotnet test command builds both projects and runs the tests. O corredor de teste xUnit contém o ponto de entrada do programa para executar os testes.The xUnit test runner contains the program entry point to run the tests. dotnet testinicia o corredor de teste usando o projeto de teste da unidade.dotnet test starts the test runner using the unit test project.

O teste IsPrime falha porque não foi implementado.The test fails because IsPrime hasn't been implemented. Usando a abordagem TDD, escreva apenas código suficiente para que este teste passe.Using the TDD approach, write only enough code so this test passes. Atualize IsPrime com o seguinte código:Update IsPrime with the following code:

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

Execute dotnet test.Run dotnet test. O teste é aprovado.The test passes.

Adicione mais testesAdd more tests

Adicione testes de número primo para 0 e -1.Add prime number tests for 0 and -1. Você pode copiar o teste anterior e alterar o seguinte código para usar 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");

Copiar o código do teste quando apenas um parâmetro muda resulta em duplicação de código e inchaço do teste.Copying test code when only a parameter changes results in code duplication and test bloat. Os seguintes atributos xUnit permitem escrever um conjunto de testes semelhantes:The following xUnit attributes enable writing a suite of similar tests:

  • O [Theory] representa um pacote de testes que executa o mesmo código, mas têm diferentes argumentos de entrada.[Theory] represents a suite of tests that execute the same code but have different input arguments.

  • O atributo [InlineData] especifica valores para essas entradas.[InlineData] attribute specifies values for those inputs.

Em vez de criar novos testes, aplique os atributos xUnit anteriores para criar uma única teoria.Rather than creating new tests, apply the preceding xUnit attributes to create a single theory. Substitua o código a seguir:Replace the following code:

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

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

pelo código a seguir: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");
}

No código [Theory] anterior, [InlineData] e habilite testar vários valores menores que dois.In the preceding code, [Theory] and [InlineData] enable testing several values less than two. Dois é o menor número primo.Two is the smallest prime number.

Run, dotnet testdois dos testes falham.Run dotnet test, two of the tests fail. Para fazer com que todos IsPrime os testes passem, atualize o método com o seguinte código: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.");
}

Seguindo a abordagem TDD, adicione mais testes de falha e atualize o código de destino.Following the TDD approach, add more failing tests, then update the target code. Veja a versão finalizada dos testes e a implementação completa da biblioteca.See the finished version of the tests and the complete implementation of the library.

O IsPrime método completo não é um algoritmo eficiente para testar a primalidade.The completed IsPrime method is not an efficient algorithm for testing primality.

Recursos adicionaisAdditional resources