Compartir a través de


Pruebas unitarias de bibliotecas de F# mediante dotnet test y NUnit

Este tutorial le lleva a través de una experiencia interactiva que crea una solución de ejemplo paso a paso para aprender conceptos de pruebas unitarias. Si prefiere seguir el tutorial mediante una solución precompilada, vea o descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, consulte Ejemplos y tutoriales.

En este artículo se trata de probar un proyecto de .NET Core. Si vas a probar un proyecto de ASP.NET Core, consulta Pruebas de integración en ASP.NET Core.

Prerrequisitos

  • SDK de .NET 8 o versiones posteriores.
  • El editor de texto o de código que elija.

Creación del proyecto de origen

Abra una ventana de terminal. Cree un directorio denominado unit-testing-with-fsharp para contener la solución. Dentro de este nuevo directorio, ejecute el siguiente comando para crear un nuevo archivo de solución para la biblioteca de clases y el proyecto de prueba:

dotnet new sln

A continuación, cree un directorio MathService . En el esquema siguiente se muestra la estructura de directorios y archivos hasta ahora:

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

Convierta MathService en el directorio actual y ejecute el siguiente comando para crear el proyecto de origen:

dotnet new classlib -lang "F#"

Usted crea una implementación defectuosa del servicio matemático.

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

Cambie de nuevo al directorio unit-testing-with-fsharp. Ejecute el siguiente comando para agregar el proyecto de biblioteca de clases a la solución:

dotnet sln add .\MathService\MathService.fsproj

Creación del proyecto de prueba

A continuación, cree el directorio MathService.Tests . En el esquema siguiente se muestra la estructura de directorios:

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

Convierta el directorio MathService.Tests en el directorio actual y cree un nuevo proyecto con el comando siguiente:

dotnet new nunit -lang "F#"

Este comando crea un proyecto de prueba que usa NUnit como marco de pruebas. La plantilla generada configura el ejecutor de pruebas en 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>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso anterior se agregó NUnit y el adaptador de prueba de NUnit. Ahora, agregue la biblioteca de clases MathService como otra dependencia al proyecto. Use el comando dotnet reference add:

dotnet reference add ../MathService/MathService.fsproj

Puede ver todo el archivo en el repositorio de ejemplos de en GitHub.

Tiene el siguiente diseño de solución final:

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

Ejecute el siguiente comando en el directorio unit-testing-with-fsharp :

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

Creación de la primera prueba

Escriba una prueba que falla, hágala pasar, y luego repita el proceso. Abra UnitTest1.fs y agregue el código siguiente:

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)

El [<TestFixture>] atributo denota una clase que contiene pruebas. El [<Test>] atributo denota un método de prueba que ejecuta el ejecutor de pruebas. En el directorio unit-testing-with-fsharp , ejecute dotnet test para compilar las pruebas y la biblioteca de clases y, a continuación, ejecute las pruebas. El ejecutor de pruebas NUnit contiene el punto de entrada del programa para ejecutar las pruebas. dotnet test inicia el ejecutor de pruebas mediante el proyecto de prueba unitaria que ha creado.

Estas dos pruebas muestran las pruebas superadas y con errores más básicas. My test indica que se supera y Fail every time indica que no. Ahora, cree una prueba para el squaresOfOdds método . El squaresOfOdds método devuelve una secuencia de los cuadrados de todos los valores enteros impares que forman parte de la secuencia de entrada. En lugar de intentar escribir todas esas funciones a la vez, puede crear pruebas iterativamente que validen la funcionalidad. Superar cada prueba significa crear la funcionalidad necesaria para el método.

La prueba más sencilla que puede escribir es llamar a squaresOfOdds con todos los números pares, donde el resultado debe ser una secuencia vacía de enteros. Esta es la prueba:

[<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 la expected secuencia se convierte en una lista. El marco NUnit se basa en muchos tipos estándar de .NET. Esa dependencia significa que la interfaz pública y los resultados esperados admiten ICollection en lugar de IEnumerable.

Al ejecutar la prueba, verá que se produce un error en la prueba. Esto se debe a que aún no ha creado la implementación. Haga que esta prueba pase escribiendo el código más sencillo en la clase Library.fs del proyecto MathService que funciona:

let squaresOfOdds xs =
    Seq.empty<int>

En el directorio unit-testing-with-fsharp, vuelva a ejecutar dotnet test. El comando dotnet test ejecuta una compilación para el proyecto de MathService y, a continuación, para el proyecto de MathService.Tests. Después de compilar ambos proyectos, las pruebas se ejecutan. Ahora se superan dos pruebas.

Completar los requisitos

Ahora que la prueba se ha superado, es el momento de escribir más. El siguiente caso sencillo funciona con una secuencia cuyo único número impar es 1. El número 1 es más fácil porque el cuadrado de 1 es 1. Esta es la siguiente prueba:

[<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))

La ejecución de dotnet test falla en la nueva prueba. Debe actualizar el squaresOfOdds método para controlar esta nueva prueba. Debe filtrar todos los números pares de la secuencia para pasar esta prueba. Para ello, escriba una función de filtro pequeña y use Seq.filter:

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd

Queda un paso más por hacer: cuadrar cada uno de los números impares. Comience escribiendo una prueba nueva:

[<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))

Puede corregir la prueba si canaliza la secuencia filtrada a través de una operación de asignación para calcular el cuadrado de cada número impar:

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

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

Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la solución para que la adición de nuevos paquetes y pruebas forme parte del flujo de trabajo normal. Ha concentrado la mayor parte de su tiempo y esfuerzo en resolver los objetivos de la aplicación.

Consulte también