C# de teste de unidade com MSTest e .NET

Este tutorial apresenta uma experiência interativa de compilação de uma solução de exemplo passo a passo para aprender os conceitos do teste de unidade. Se você preferir acompanhar o tutorial usando uma solução interna, veja ou baixe o exemplo de código antes de começar. Para obter instruções de download, consulte Exemplos e tutoriais.

Este artigo é sobre como testar um projeto do .NET Core. Se você estiver testando um projeto ASP.NET Core, confira Testes de integração no ASP.NET Core.

Pré-requisitos

Crie o projeto de origem

Abra uma janela do shell. Crie um diretório chamado unit-testing-using-mstest no qual manter a solução. Nesse diretório, execute dotnet new sln a fim de criar um novo arquivo de solução para a biblioteca de classes e o projeto de teste. Crie um diretório PrimeService. O seguinte esquema mostra a estrutura de arquivo e diretório até aqui:

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

Torne PrimeService o diretório atual e execute dotnet new classlib para criar o projeto de origem. Renomeie Class1.cs como PrimeService.cs. Substitua o código no arquivo pelo código a seguir para criar uma implementação com falha da classe PrimeService:

using System;

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

Altere o diretório de volta para o diretório unit-testing-using-mstest. Execute dotnet sln add para adicionar o projeto de biblioteca de classes à solução:

dotnet sln add PrimeService/PrimeService.csproj

Criar um projeto de teste

Crie o diretório PrimeService.Tests. O seguinte esquema mostra a estrutura do diretório:

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

Torne o diretório PrimeService.Tests o diretório atual e crie um novo projeto usando dotnet new mstest. O comando dotnet new cria um projeto de teste que usa o MSTest como a biblioteca de teste. O modelo configura o executor de teste no arquivo PrimeServiceTests.csproj:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
  <PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
  <PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
  <PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>

O projeto de teste requer outros pacotes para criar e executar testes de unidade. dotnet new na etapa anterior, adicionamos o SDK do MSTest, a estrutura de teste do MSTest, o executor do MSTest e o coverlet para relatórios de cobertura de código.

Adicione a biblioteca de classes PrimeService como outra dependência para o projeto. Use o comando dotnet add reference:

dotnet add reference ../PrimeService/PrimeService.csproj

Você pode ver o arquivo inteiro no repositório de exemplos no GitHub.

O seguinte esquema mostra o layout da solução final:

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

Altere para o diretório unit-testing-using-mstest e execute dotnet sln add:

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

Crie o primeiro teste

Grave um teste com falha, faça-o passar e repita o processo. Remova UnitTest1.cs do diretório PrimeService.Tests e crie um novo arquivo C# chamado PrimeService_IsPrimeShould.cs com o seguinte conteúdo:

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 should not be prime");
        }
    }
}

O atributo TestClass indica uma classe que contém testes de unidade. O atributo TestMethod indica um método que é um método de teste.

Salve esse arquivo e execute dotnet test para compilar os testes e a biblioteca de classes e, em seguida, execute os testes. O executor de teste do MSTest contém o ponto de entrada do programa para executar os testes. dotnet test inicia o executor de teste usando o projeto de teste de unidade que você criou.

O teste falha. Você ainda não criou a implementação. Faça esse teste ser aprovado escrevendo o código mais simples na classe PrimeService que funciona:

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

No diretório unit-testing-using-mstest, execute dotnet test novamente. O comando dotnet test executa uma compilação para o projeto PrimeService e, depois, para o projeto PrimeService.Tests. Depois de compilar os dois projetos, ele executará esse teste único. Ele é aprovado.

Adicionar mais recursos

Agora que você fez um teste ser aprovado, é hora de escrever mais. Existem alguns outros casos simples de números primos: 0, -1. Você pode adicionar novos testes com o atributo TestMethod, mas isso se torna rapidamente entediante. Há outros atributos do MSTest que permitem escrever um pacote de testes semelhantes. Um método de teste poderá executar o mesmo código, mas terá argumentos de entrada diferentes. Você pode usar o atributo DataRow para especificar valores para essas entradas.

Em vez de criar novos testes, aplique esses dois atributos para criar um único teste orientado a dados. O teste controlado por dados é um método que testa vários valores menores que dois, que é o menor número primo. Adicione um novo método de teste em PrimeService_IsPrimeShould.cs:

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

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

Execute dotnet test, e dois desses testes falham. Para fazer com que todos os testes sejam aprovados, altere a cláusula if no início do método IsPrime no arquivo PrimeService.cs:

if (candidate < 2)

Continue iterando adicionando mais testes, mais teorias e mais código na biblioteca principal. Você tem a versão concluída dos testes e a implementação completa da biblioteca.

Você criou uma pequena biblioteca e um conjunto de testes de unidade para essa biblioteca. Você estruturou a solução para que a adição de novos pacotes e testes fizesse parte do fluxo de trabalho normal. Você concentrou grande parte do seu tempo e esforço em resolver as metas do aplicativo.

Confira também