Teste de unidade de bibliotecas do .NET Core do Visual Basic usando dotnet test e NUnit

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

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

Criando o projeto de origem

Abra uma janela do shell. Crie um diretório chamado unit-testing-vb-nunit para armazenar a solução. Nesse diretório, execute o seguinte comando a fim de 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. O seguinte contorno mostra a estrutura de arquivos até agora:

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService

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

dotnet new classlib -lang VB

Renomeie Class1.VB para PrimeService.VB. Crie uma implementação com falha da classe PrimeService:

Namespace Prime.Services
    Public Class PrimeService
        Public Function IsPrime(candidate As Integer) As Boolean
            Throw New NotImplementedException("Please create a test first.")
        End Function
    End Class
End Namespace

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

dotnet sln add .\PrimeService\PrimeService.vbproj

Criando o projeto de teste

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

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService
        Source Files
        PrimeService.vbproj
    /PrimeService.Tests

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

dotnet new nunit -lang VB

O comando dotnet new cria um projeto de teste que usa o NUnit como a biblioteca de teste. O modelo gerado configura o executor de teste no arquivo PrimeServiceTests.vbproj:

<ItemGroup>
  <PackageReference Include="nunit" Version="4.2.2" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
</ItemGroup>

Observação

Antes do .NET 9, o código gerado pode referenciar versões mais antigas da estrutura de teste do NUnit. Você pode usar a CLI do dotnet para atualizar os pacotes. Como alternativa, abra o arquivo PrimeService.Tests.vbproj e substitua o conteúdo do grupo de itens de referência do pacote pelo código acima.

O projeto de teste requer outros pacotes para criar e executar testes de unidade. O dotnet new na etapa anterior adicionou o NUnit e o adaptador de teste do NUnit. Agora, adicione a biblioteca de classes PrimeService como outra dependência ao projeto. Use o comando dotnet add reference:

dotnet add reference ../PrimeService/PrimeService.vbproj

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

Você tem o seguinte layout de solução final:

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService
        Source Files
        PrimeService.vbproj
    /PrimeService.Tests
        Test Source Files
        PrimeService.Tests.vbproj

Execute o seguinte comando no diretório unit-testing-vb-nunit:

dotnet sln add .\PrimeService.Tests\PrimeService.Tests.vbproj

Criando o primeiro teste

Escreva um teste com falha, faça-o ser aprovado e, em seguida, repita o processo. No diretório PrimeService.Tests, renomeie o arquivo UnitTest1.vb para PrimeService_IsPrimeShould.VB e substitua todo o seu conteúdo pelo seguinte código:

Imports NUnit.Framework

Namespace PrimeService.Tests
    <TestFixture>
    Public Class PrimeService_IsPrimeShould
        Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

        <Test>
        Sub IsPrime_InputIs1_ReturnFalse()
            Dim result As Boolean = _primeService.IsPrime(1)

            Assert.That(result, [Is].False, $"1 should not be prime")
        End Sub

    End Class
End Namespace

O atributo <TestFixture> indica uma classe que contém testes. O atributo <Test> indica um método que é executado pelo executor de teste. Em unit-testing-vb-nunit, execute dotnet test para criar os testes e a biblioteca de classes e, em seguida, execute os testes. O executor de teste do NUnit 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 Function IsPrime(candidate As Integer) As Boolean
    If candidate = 1 Then
        Return False
    End If
    Throw New NotImplementedException("Please create a test first.")
End Function

No diretório unit-testing-vb-nunit, 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.

Adicionando 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 esses casos como novos testes com o atributo <Test>, mas isso se torna entediante rapidamente. Há outros atributos de xUnit que permitem escrever um pacote de testes semelhantes. Um atributo <TestCase> representa um pacote de testes que executa o mesmo código, mas têm diferentes argumentos de entrada. Você pode usar o atributo <TestCase> para especificar valores para essas entradas.

Em vez de criar novos testes, aplique esses dois atributos para criar uma série de testes que testa diversos valores menores que dois, que é o menor número primo:

<TestFixture>
Public Class PrimeService_IsPrimeShould
    Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

    <TestCase(-1)>
    <TestCase(0)>
    <TestCase(1)>
    Sub IsPrime_ValuesLessThan2_ReturnFalse(value As Integer)
        Dim result As Boolean = _primeService.IsPrime(value)

        Assert.That(result, [Is].False, $"{value} should not be prime")
    End Sub

    <TestCase(2)>
    <TestCase(3)>
    <TestCase(5)>
    <TestCase(7)>
    Public Sub IsPrime_PrimesLessThan10_ReturnTrue(value As Integer)
        Dim result As Boolean = _primeService.IsPrime(value)

        Assert.That(result, [Is].True, $"{value} should be prime")
    End Sub

    <TestCase(4)>
    <TestCase(6)>
    <TestCase(8)>
    <TestCase(9)>
    Public Sub IsPrime_NonPrimesLessThan10_ReturnFalse(value As Integer)
        Dim result As Boolean = _primeService.IsPrime(value)

        Assert.That(result, [Is].False, $"{value} should not be prime")
    End Sub
End Class

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 Main no arquivo PrimeServices.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.