Teste de unidade C# com TUnit e .NET

Este tutorial guia você por uma experiência interativa de construção de uma solução de exemplo passo a passo para aprender conceitos de teste de unidade.

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

Prerequisites

  • .NET 10 SDK ou versões posteriores.
  • Um editor de texto ou editor de código de sua escolha.

O TUnit é criado inteiramente em Microsoft. Testing.Platform (MTP) e não dá suporte ao VSTest. Este tutorial usa o modo MTP dedotnet test, que requer o SDK .NET 10.

Criando o projeto de origem

Abra uma janela do shell. Crie um diretório chamado unit-testing-using-tunit para manter a solução. Dentro desse novo diretório, execute o seguinte comando para criar um novo arquivo de solução para a biblioteca de classes e o projeto de teste:

dotnet new sln

Em seguida, crie um diretório PrimeService . A estrutura de diretório e arquivos até agora é a seguinte:

/unit-testing-using-tunit
    unit-testing-using-tunit.slnx
    /PrimeService

Torne o PrimeService o diretório atual e execute o seguinte comando para criar o projeto de origem:

dotnet new classlib

Renomeie Class1.cs para PrimeService.cs. Você cria 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-tunit . Execute o seguinte comando para adicionar o projeto de biblioteca de classes à solução:

dotnet sln add PrimeService/PrimeService.csproj

Criando o projeto de teste

Em seguida, crie o diretório PrimeService.Tests. O seguinte esquema mostra a estrutura do diretório:

/unit-testing-using-tunit
    unit-testing-using-tunit.slnx
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

Os modelos de projeto do TUnit não estão incluídos no SDK do .NET. Instale-os com o seguinte comando:

dotnet new install TUnit.Templates

Altere o diretório para o diretório PrimeService.Tests e crie um novo projeto usando o seguinte comando:

dotnet new TUnit

Note

Os nomes curtos do modelo são sensíveis a maiúsculas e minúsculas. Use TUnit, não tunit.

O comando dotnet new cria um projeto de teste que usa o TUnit como a biblioteca de teste. O arquivo PrimeService.Tests.csproj gerado é um projeto executável que faz referência ao TUnit pacote (o número de versão pode ser diferente):

<PropertyGroup>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <OutputType>Exe</OutputType>
  <TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="TUnit" Version="1.*" />
</ItemGroup>

O TUnit pacote inclui a estrutura de teste, a biblioteca de asserções e o executor de teste mtp, de modo que o projeto não precisa de nenhum outro pacote de teste. O modelo também adiciona testes de exemplo. Exclua todos os arquivos .cs e o diretório Data do diretório PrimeService.Tests, pois este tutorial os substitui por seus próprios testes.

Agora, adicione a biblioteca de classes PrimeService como outra dependência ao projeto. Use o comando dotnet reference add:

dotnet reference add ../PrimeService/PrimeService.csproj

O esboço a seguir mostra o esquema final da solução.

/unit-testing-using-tunit
    unit-testing-using-tunit.slnx
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeService.Tests.csproj

Execute o seguinte comando no diretório unit-testing-using-tunit :

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

Configurando o modo MTP do dotnet test

Como o TUnit não dá suporte ao VSTest, dotnet test deve ser executado em seu modo MTP. No diretório unit-testing-using-tunit , crie um arquivo global.json com o seguinte conteúdo:

{
    "test": {
        "runner": "Microsoft.Testing.Platform"
    }
}

Para obter mais informações, consulte o modo MTP do dotnet test.

Criando o primeiro teste

Você escreve um teste que falha, faz com que ele passe, e então repete o processo. No diretório PrimeService.Tests, crie um arquivo PrimeService_IsPrimeShould.cs com o seguinte código:

namespace Prime.UnitTests.Services
{
    using Prime.Services;

    public class PrimeService_IsPrimeShould
    {
        private readonly PrimeService _primeService = new();

        [Test]
        public async Task IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            await Assert.That(result).IsFalse();
        }
    }
}

O [Test] atributo indica que um método é um método de teste. O TUnit não precisa de um atributo na classe. As asserções de TUnit são assíncronas, portanto, o método de teste retorna um Task e aguarda Assert.That. O TUnit pacote adiciona diretivas globais using para seus namespaces, de modo que o arquivo não precisa delas.

Note

A using Prime.Services; diretiva está dentro do namespace de propósito. O MTP gera o ponto de entrada do aplicativo de teste no namespace raiz do projeto, PrimeService.Tests. Esse namespace oculta a PrimeService classe de uma using diretiva na parte superior do arquivo, mas não de uma dentro do namespace.

Salve esse arquivo e execute o dotnet test comando para criar os testes e a biblioteca de classes e executar os testes. O projeto de teste do TUnit contém o ponto de entrada do programa para executar seus testes. dotnet test inicia o aplicativo 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 o teste passar escrevendo o código mais simples na PrimeService classe 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-tunit , execute dotnet test novamente. O comando dotnet test executa um build para o projeto PrimeService e, em seguida, para o projeto PrimeService.Tests. Depois de compilar ambos os projetos, ele executará este único teste. Ele passa.

Adicionando mais recursos

Agora que você fez uma aprovação de teste, é hora de escrever mais. Há alguns outros casos simples para números primos: 0, -1. Você pode adicionar novos testes com o [Test] atributo, mas isso rapidamente se torna entediante. O TUnit fornece o [Arguments] atributo para criar um conjunto de testes que executam o mesmo código, mas têm argumentos de entrada diferentes.

Em vez de criar novos testes, aplique esse atributo para criar um único teste controlado por dados. Substitua o IsPrime_InputIs1_ReturnFalse método pelo seguinte código. O teste controlado por dados é um método que testa vários valores menores que dois, que é o número principal mais baixo:

[Test]
[Arguments(-1)]
[Arguments(0)]
[Arguments(1)]
public async Task IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);

    await Assert.That(result).IsFalse();
}

Execute dotnet teste dois desses testes falharão. Para que todos os testes passem, altere a if cláusula no início do IsPrime método no arquivo PrimeService.cs :

if (candidate < 2)

Continue a iterar adicionando mais testes e código na biblioteca principal.

Você criou uma pequena biblioteca e um conjunto de testes de unidade para essa biblioteca. Você também estruturou a solução para que a adição de novos pacotes e testes faça parte do fluxo de trabalho padrão. Você concentrou a maior parte do seu tempo e esforço na resolução das metas do aplicativo.

Consulte também