Partilhar via


Testes de unidade em bibliotecas F# usando dotnet test e NUnit

Este tutorial leva você através de uma experiência interativa criando uma solução de exemplo passo a passo para aprender conceitos de teste de unidade. Se preferir seguir o tutorial usando uma solução pré-criada, visualize ou baixe o código de exemplo antes de começar. Para obter instruções de download, consulte Exemplos e tutoriais.

Este artigo é sobre como testar um projeto .NET Core. Se você estiver testando um projeto ASP.NET Core, consulte 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 da sua preferência.

Criar o projeto de origem

Abra uma janela de terminal. Crie um diretório chamado unit-testing-with-fsharp para armazenar 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 MathService . O seguinte esboço apresenta o diretório e a estrutura de ficheiros até agora:

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService

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

dotnet new classlib -lang "F#"

Você cria uma implementação com falha do serviço de matemática:

module MyMath =
    let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Volte para o diretório unit-testing-with-fsharp. Execute o seguinte comando para adicionar o projeto de biblioteca de classes à solução:

dotnet sln add .\MathService\MathService.fsproj

Criar o projeto de teste

Em seguida, crie o diretório MathService.Tests. O esquema a seguir mostra a estrutura de diretórios:

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests

Faça do diretório MathService.Tests o diretório atual e crie um novo projeto usando o seguinte comando:

dotnet new nunit -lang "F#"

Este comando cria um projeto de teste que usa NUnit como a estrutura de teste. O modelo gerado configura o executor de testes no projeto MathServiceTests.fsproj:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
  <PackageReference Include="NUnit" Version="4.1.0" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

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

dotnet reference add ../MathService/MathService.fsproj

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

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

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests
        Test Source Files
        MathService.Tests.fsproj

Execute o seguinte comando no diretório unit-testing-with-fsharp :

dotnet sln add .\MathService.Tests\MathService.Tests.fsproj

Criar o primeiro teste

Escreve um teste que falha, faz com que passe, depois repete o processo. Abra UnitTest1.fs e adicione o seguinte código:

namespace MathService.Tests

open System
open NUnit.Framework
open MathService

[<TestFixture>]
type TestClass () =

    [<Test>]
    member this.TestMethodPassing() =
        Assert.That(true, Is.True)

    [<Test>]
     member this.FailEveryTime() = Assert.That(false, Is.True)

O atributo [<TestFixture>] denota uma classe que contém testes. O atributo [<Test>] indica um método de teste que é executado pelo executor de teste. A partir do diretório unit-testing-with-fsharp, execute dotnet test para criar os testes e a biblioteca de classes e, em seguida, execute os testes. O executor de teste NUnit contém o ponto de entrada do programa para executar seus testes. dotnet test inicia o executor de teste usando o projeto de teste de unidade que você criou.

Estes dois testes mostram os testes mais básicos de aprovação e reprovação. My test passa e Fail every time falha. Agora, crie um teste para o método squaresOfOdds. O squaresOfOdds método retorna uma sequência dos quadrados de todos os valores inteiros ímpares que fazem parte da sequência de entrada. Em vez de tentar escrever todas essas funções de uma só vez, você pode criar iterativamente testes que validam a funcionalidade. Para fazer com que cada teste seja aprovado, crie a funcionalidade necessária para o método.

O teste mais simples que pode escrever é chamar squaresOfOdds com todos os números pares, devendo resultar numa sequência vazia de inteiros. Aqui está esse teste:

[<Test>]
member this.TestEvenSequence() =
    let expected = Seq.empty<int>
    let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
    Assert.That(actual, Is.EqualTo(expected))

Observe que a expected sequência é convertida em uma lista. A estrutura NUnit depende de muitos tipos .NET padrão. Essa dependência significa que sua interface pública e os resultados esperados suportam ICollection em vez de IEnumerable.

Quando você executa o teste, você vê que o teste falha. Isso porque você ainda não criou a implementação. Faça este teste passar escrevendo o código mais simples na classe Library.fs em seu projeto MathService que funciona:

let squaresOfOdds xs =
    Seq.empty<int>

No diretório unit-testing-with-fsharp, execute dotnet test novamente. O comando dotnet test executa uma compilação para o projeto MathService e, em seguida, para o projeto MathService.Tests. Depois de construir ambos os projetos, ele executa seus testes. Dois testes passam agora.

Preencha os requisitos

Agora que você fez um teste aprovado, é hora de escrever mais. O próximo caso simples funciona com uma sequência cujo único número ímpar é 1. O número 1 é mais fácil porque o quadrado de 1 é 1. Este é o próximo teste:

[<Test>]
member public this.TestOnesAndEvens() =
    let expected = [1; 1; 1; 1]
    let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
    Assert.That(actual, Is.EqualTo(expected))

A execução dotnet test falha no(s) novo(s) teste(s). Você deve atualizar o método squaresOfOdds para manipular esse novo teste. Você deve filtrar todos os números pares fora da sequência para fazer este teste passar. Você pode fazer isso escrevendo uma pequena função de filtro e usando Seq.filter:

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd

Há mais um passo a percorrer: quadrar cada um dos números ímpares. Comece por escrever um novo teste:

[<Test>]
member public this.TestSquaresOfOdds() =
    let expected = [1; 9; 25; 49; 81]
    let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
    Assert.That(actual, Is.EqualTo(expected))

Você pode corrigir o teste canalizando a sequência filtrada através de uma operação de mapa para calcular o quadrado de cada número ímpar:

let private square x = x * x
let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd
    |> Seq.map square

Você criou uma pequena biblioteca e um conjunto de testes unitários para essa biblioteca. Você estruturou a solução para que a adição de novos pacotes e testes faça parte do fluxo de trabalho normal. Você concentrou a maior parte do seu tempo e esforço na resolução dos objetivos do aplicativo.

Ver também