Prueba unitaria de C# con NUnit y .NET Core

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y tutoriales.

Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Requisitos previos

  • .NET 8.0 o versiones posteriores.
  • Un editor de texto o un editor de código de su elección.

Crear el proyecto de origen

Abra una ventana del Shell. Cree un directorio llamado unit-testing-using-nunit que contenga la solución. En este directorio nuevo, ejecute el comando siguiente para crear un archivo de solución nuevo para la biblioteca de clases y el proyecto de prueba:

dotnet new sln

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

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

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

dotnet new classlib

Cambie el nombre de Class1.cs a PrimeService.cs. Creará una implementación de errores de la clase PrimeService:

using System;

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

Cambie nuevamente el directorio a unit-testing-using-nunit. Ejecute el siguiente comando para agregar el proyecto de biblioteca de clases a la solución:

dotnet sln add PrimeService/PrimeService.csproj

Crear el proyecto de prueba

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

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

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

dotnet new nunit

El comando dotnet new crea un proyecto de prueba que usa NUnit como la biblioteca de pruebas. La plantilla generada configura el ejecutor de pruebas en el archivo PrimeService.Tests.csproj:

<ItemGroup>
  <PackageReference Include="nunit" Version="4.1.0" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
  <PackageReference Include="NUnit.Analyzers" Version="4.1.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
  </PackageReference>
</ItemGroup>

Nota:

Antes de .NET 9, el código generado podía hacer referencia a versiones anteriores del marco de prueba de NUnit. Use la CLI de dotnet para actualizar los paquetes. Como alternativa, abra el archivo PrimeService.Tests.csproj y reemplace el contenido del grupo de elementos de referencias del paquete por el código anterior.

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. En el paso anterior, el comando dotnet new ha agregado el SDK de prueba de Microsoft, el marco de pruebas de NUnit y el adaptador de prueba de NUnit. Ahora, agregue la biblioteca de clases PrimeService como otra dependencia al proyecto. Use el comando dotnet add reference:

dotnet add reference ../PrimeService/PrimeService.csproj

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

En el esquema siguiente se muestra el diseño de solución final:

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

Ejecute el comando siguiente en el directorio unit-testing-using-nunit:

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

Crear la primera prueba

Debe escribir una prueba de errores, aprobarla y, luego, repetir el proceso. En el directorio PrimeService.Tests, cambie el nombre del archivo UnitTest1.cs por PrimeService_IsPrimeShould.cs y reemplace todo su contenido por el código siguiente:

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestFixture]
    public class PrimeService_IsPrimeShould
    {
        private PrimeService _primeService;

        [SetUp]
        public void SetUp()
        {
            _primeService = new PrimeService();
        }

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

            Assert.That(result, Is.False, "1 should not be prime");
        }
    }
}

El atributo [TestFixture] indica una clase que contiene pruebas unitarias. El atributo [Test] indica que un método es un método de prueba.

Guarde este archivo y ejecute el comando dotnet test para compilar las pruebas y la biblioteca de clases y, después, ejecutar las pruebas. El ejecutor de pruebas de NUnit tiene el punto de entrada del programa para ejecutar las pruebas desde la consola. dotnet test inicia el ejecutor de pruebas con el proyecto de prueba unitaria que creó.

La prueba produce un error. Todavía no ha creado la implementación. Consiga que la prueba se supere escribiendo el código más simple en la clase PrimeService que funciona:

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

En el directorio unit-testing-using-nunit, vuelva a ejecutar dotnet test. El comando dotnet test ejecuta una compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests. Después de compilar ambos proyectos, se ejecuta esta única prueba. Pasa.

Agregar más características

Ahora que la prueba se ha superado, es el momento de escribir más. Hay algunos otros casos simples para números primos: 0, -1. Puede agregar pruebas nuevas con el atributo [Test], pero enseguida este proceso se hace tedioso. Hay otros atributos de NUnit que le permiten escribir un conjunto de pruebas similares. Un atributo [TestCase] se usa para crear un conjunto de pruebas que ejecutan el mismo código pero tienen diferentes argumentos de entrada. Puede usar el atributo [TestCase] para especificar valores para esas entradas.

En lugar de crear pruebas, aplique este atributo para crear una sola prueba controlada por datos. La prueba controlada por datos es un método que prueba varios valores menores que dos, que es el número primo menor:

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

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

Ejecute dotnet test, y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula if al principio del método Main en el archivo PrimeService.cs:

if (candidate < 2)

Continue recorriendo en iteración agregando más pruebas, teorías y código en la biblioteca principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.

Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. También ha estructurado la solución, por lo que agregar pruebas y paquetes nuevos forma parte del flujo de trabajo estándar. Ha centrado la mayor parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.