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 criar uma solução que contém um projeto de teste de unidade e um 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 predefinida, exiba ou baixe o código de exemplo.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 os projetos de origem e 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 solução de teste para obter instruções para criar a solução de teste em uma única 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 seguinte comando: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 Unit-Testing-using-dotnet-Test .The dotnet new sln command creates a new solution in the unit-testing-using-dotnet-test directory.

  • Altere o diretório para a pasta Unit-Testing-using-dotnet-Test .Change directory to the unit-testing-using-dotnet-test folder.

  • Execute o seguinte comando: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 classes 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:

    • Gera um NotImplementedException com uma mensagem indicando que não está implementado.Throws a NotImplementedException with a message indicating it's not implemented.
    • Será atualizado posteriormente no tutorial.Is updated later in the tutorial.
  • No diretório Unit-Testing-using-dotnet-Test , execute o seguinte comando para adicionar o projeto de biblioteca de classes à 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 a biblioteca de teste.The test project uses xUnit as the test library.
    • Configura o executor de teste adicionando os seguintes <PackageReference /> elementos ao arquivo de 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 de 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 a PrimeService 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 na seção anterior.This section summarizes all the commands in the previous section. Ignore 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 um computador Windows.The following commands create the test solution on a windows machine. Para macOS e UNIX, atualize o ren comando para a versão do sistema operacional do ren 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 para "substituir o código em PrimeService.cs com o código a seguir" na seção anterior.Follow the instructions for "Replace the code in PrimeService.cs with the following code" in the previous section.

Criar um testeCreate a test

Uma abordagem popular no TDD (desenvolvimento controlado por teste) é 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 é chamável, mas não implementado.The IsPrime method is callable, but not implemented. Uma chamada de teste para IsPrime falha.A test call to IsPrime fails. Com o TDD, um teste é escrito que é conhecido como falha.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 com falha e, em seguida, 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 pelo código a seguir:Replace the code in PrimeService_IsPrimeShould.cs with the following code:
using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    public class PrimeService_IsPrimeShould
    {
        [Fact]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var primeService = new PrimeService();
            bool result = primeService.IsPrime(1);

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

O [Fact] atributo declara um método de teste que é executado pelo executor de teste.The [Fact] attribute declares a test method that's run by the test runner. Na pasta PrimeService. Tests , execute dotnet test .From the PrimeService.Tests folder, run dotnet test. O comando dotnet Test compila ambos os projetos e executa os testes.The dotnet test command builds both projects and runs the tests. O executor de teste do 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 test inicia o executor de teste usando o projeto de teste de unidade.dotnet test starts the test runner using the unit test project.

O teste falha porque não IsPrime foi implementado.The test fails because IsPrime hasn't been implemented. Usando a abordagem TDD, escreva apenas código suficiente para que esse 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.

Adicionar mais testesAdd more tests

Adicionar 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 código a seguir para usar 0 e-1:You could copy the preceding test and change the following code to use 0 and -1:

var primeService = new PrimeService();
bool result = primeService.IsPrime(1);

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

Copiar o código de teste quando apenas um parâmetro altera os resultados na duplicação de código e no inchar de 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 primeService = new PrimeService();
    bool 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 anterior, [Theory] e [InlineData] habilite o teste de 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 de primo.Two is the smallest prime number.

Executar dotnet test , dois dos testes falham.Run dotnet test, two of the tests fail. Para fazer todos os testes serem aprovados, atualize o IsPrime 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.");
}

Após a abordagem TDD, adicione mais testes com falha e, em seguida, atualize o código de destino.Following the TDD approach, add more failing tests, then update the target code. Consulte a versão concluída 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 concluído não é um algoritmo eficiente para testar primality.The completed IsPrime method is not an efficient algorithm for testing primality.

Recursos adicionaisAdditional resources