Conceptos básicos de las pruebas unitarias

Compruebe que el código funciona correctamente; para ello, cree y ejecute pruebas unitarias. Se llaman pruebas unitarias porque descomponen las funciones del programa en comportamientos comprobables discretos que se pueden probar como unidades individuales. El Explorador de pruebas de Visual Studio proporciona una forma flexible y eficaz de ejecutar las pruebas unitarias y ver los resultados en Visual Studio. Visual Studio instala los marcos de pruebas unitarias de Microsoft para el código administrado y nativo. Use un marco de pruebas unitarias para crear pruebas unitarias, ejecutarlas y notificar los resultados correspondientes. Cuando realice cambios, vuelva a ejecutar las pruebas unitarias para probar que el código sigue funcionando correctamente. Visual Studio Enterprise puede hacerlo automáticamente con Live Unit Testing, que detecta pruebas afectadas por los cambios en el código y las ejecuta en segundo plano mientras se escribe.

Las pruebas unitarias tienen el mayor efecto en la calidad del código cuando son parte integral del flujo de trabajo de desarrollo de software. En cuanto escriba una función u otro bloque de código de aplicación, cree pruebas unitarias que comprueben el comportamiento del código en respuesta a casos estándar, límite e incorrectos de datos de entrada, así como cualquier suposición explícita o implícita creada por el código. En el desarrollo controlado por pruebas, las pruebas unitarias se crean antes de escribir el código, de modo que se usan como documentación de diseño y como especificaciones de las funciones.

El Explorador de pruebas también puede ejecutar marcos de pruebas unitarias de terceros y de código abierto que hayan implementado interfaces complementarias del Explorador de pruebas. Muchos de estos marcos se pueden agregar a través del Administrador de extensiones de Visual Studio y la galería de Visual Studio. Para más información, vea Instalar marcos de prueba unitaria de terceros.

Puede generar rápidamente proyectos y métodos de prueba a partir del código o crear manualmente las prueba a medida que las necesite. Cuando usa IntelliTest para explorar el código .NET, puede generar datos de prueba y un conjunto de pruebas unitarias. Para cada instrucción en el código, se genera una entrada de prueba que ejecutará esa instrucción. Descubra cómo generar pruebas unitarias para código .NET.

Introducción

Para obtener una introducción a las pruebas unitarias que le guíe directamente en la codificación, vea uno de estos temas:

Ejemplo de la solución Bank

En este artículo, se utiliza el desarrollo de una aplicación ficticia denominada MyBank como ejemplo. No es necesario el código real para seguir las explicaciones de este tema. Los métodos de prueba se escriben en C# y presentan mediante el Marco de pruebas unitarias de Microsoft para código administrado. Sin embargo, los conceptos se transfieren fácilmente a otros lenguajes y marcos de trabajo.

MyBank Solution 2019

MyBank Solution 2022

Nuestro primer intento de un diseño para la aplicación MyBank incluye un componente de cuentas que representa una cuenta individual y sus transacciones con el banco, así como un componente de base de datos que representa la funcionalidad para agregar y administrar las cuentas individuales.

Creamos una solución Bank que contiene dos proyectos:

  • Accounts

  • BankDB

El primer intento en el diseño del proyecto Accounts contiene una clase para incluir información básica sobre una cuenta, una interfaz que especifica la funcionalidad común de cualquier tipo de cuenta, como el depósito y la retirada de activos de la misma, y una clase derivada de la interfaz que representa una cuenta corriente. Comenzamos los proyectos Accounts creando los archivos de código fuente siguientes:

  • AccountInfo.cs define la información básica de una cuenta.

  • IAccount.cs define una interfaz IAccount estándar para una cuenta, incluidos los métodos para depositar y retirar activos de una cuenta y recuperar el saldo de cuenta.

  • CheckingAccount.cs contiene la clase CheckingAccount que implementa la interfaz de IAccount para una cuenta corriente.

Sabemos por experiencia que al retirarse una cantidad de una cuenta corriente debe garantizarse que la cantidad retirada sea inferior al saldo de la cuenta. Por tanto, reemplazamos el método IAccount.Withdraw en CheckingAccount por un método que compruebe esta condición. El método puede presentar el siguiente aspecto:

public void Withdraw(double amount)
{
    if(m_balance >= amount)
    {
        m_balance -= amount;
    }
    else
    {
        throw new ArgumentException(nameof(amount), "Withdrawal exceeds balance!");
    }
}

Ahora que tenemos código, es el momento de probar.

Creación de proyectos de prueba unitaria y métodos de prueba (C#)

Para C#, a menudo es más rápido generar el proyecto de prueba unitaria y los códigos auxiliares de pruebas unitarias a partir del código, aunque también puede crear el proyecto y las pruebas manualmente según sus requisitos. Si quiere crear pruebas unitarias a partir de código con un marco de terceros, necesitará tener una de las siguientes extensiones instaladas: NUnit o xUnit. Si no usa C#, omita esta sección y vaya a Crear el proyecto de pruebas unitarias y las pruebas manualmente.

Generar el proyecto de prueba unitaria y los códigos auxiliares correspondientes

  1. En la ventana del editor de código, haga clic con el botón derecho y seleccione Crear pruebas unitarias en el menú contextual.

    From the editor window, view the context menu

    Nota:

    El comando de menú Crear pruebas unitarias solo está disponible para código de C#. Para usar este método con .NET Core o .NET Standard, se requiere Visual Studio 2019 o versiones posteriores.

    From the editor window, view the context menu

    Nota:

    El comando de menú Crear pruebas unitarias solo está disponible para código de C#. Para usar este método con .NET Core o .NET Standard, se requiere Visual Studio 2019 o versiones posteriores.

  2. Haga clic en Aceptar para aceptar los valores predeterminados al crear las pruebas unitarias o cambiar los valores usados para crear las pruebas unitarias y el proyecto que las engloba, y asignarles un nombre. Puede seleccionar el código que se agrega de forma predeterminada a los métodos de prueba unitaria.

    Create Unit Tests dialog box in Visual Studio

    Create Unit Tests dialog box in Visual Studio

  3. El código auxiliar de prueba unitaria se crea en un proyecto de prueba unitaria nuevo para todos los métodos de la clase.

    The unit tests are created

    The unit tests are created

  4. Avance para saber cómo Escribir las pruebas para que la prueba unitaria tenga significado y cómo agregar pruebas unitarias adicionales para probar exhaustivamente el código.

Crear el proyecto de pruebas unitarias y las pruebas manualmente

Un proyecto de prueba unitaria suele reflejar la estructura de un solo proyecto de código. En el ejemplo de MyBank, se agregan dos proyectos de prueba unitaria denominados AccountsTests y BankDbTests a la solución Bank . Los nombres del proyecto de prueba son arbitrarios, pero es recomendable adoptar una convención de nomenclatura estándar.

Para agregar un proyecto de prueba unitaria a una solución:

  1. En el Explorador de soluciones, haga clic con el botón derecho en la solución y elija Agregar>NuevoProyecto.

  2. Escriba prueba en el cuadro de búsqueda de plantillas de proyecto para encontrar una plantilla de proyecto de prueba unitaria para el marco de pruebas que quiere utilizar. (En los ejemplos de este tema, usamos MSTest).

  3. En la página siguiente, asigne un nombre al proyecto. Para probar el proyecto Accounts del ejemplo, podría asignarle el nombre AccountsTests.

  4. En el proyecto de prueba unitaria, agregue una referencia al proyecto de código en pruebas, en el ejemplo para el proyecto Accounts.

    Para crear la referencia al proyecto de código:

    1. En el proyecto de prueba unitaria del Explorador de soluciones, haga clic con el botón derecho en el nodo Referencias o Dependencias y elija Agregar referencia de proyecto o Agregar referencia, la opción que esté disponible.

    2. En el cuadro de diálogo Administrador de referencias, abra el nodo Solución y elija Proyectos. Seleccione el nombre del proyecto de código y cierre el cuadro de diálogo.

Cada proyecto de prueba unitaria contiene clases que reflejan los nombres de las clases en el proyecto de código. En nuestro ejemplo, el proyecto AccountsTests contendría las clases siguientes:

  • La claseAccountInfoTests contiene los métodos de prueba unitaria para la clase AccountInfo del proyecto Accounts .

  • La claseCheckingAccountTests contiene los métodos de prueba unitaria para la clase CheckingAccount .

Escribir las pruebas

El marco de pruebas unitarias que use y Visual Studio IntelliSense le guiarán en la escritura del código de las pruebas unitarias para un proyecto de código. Para ejecutar en el Explorador de pruebas, la mayoría de los marcos requieren que se agreguen atributos específicos para identificar métodos de prueba unitaria. Los marcos también ofrecen una manera (normalmente a través de instrucciones assert o atributos method) de indicar si el método de prueba se ha superado o no. Otros atributos identifican métodos de configuración opcionales que están en la inicialización de la clase y antes de cada método de prueba y métodos de destrucción que se ejecutan después de cada método de prueba y antes de que la clase se destruya.

El patrón AAA (Arrange, Act, Assert) es una forma habitual de escribir pruebas unitarias para un método en pruebas.

  • La sección Arrange de un método de prueba unitaria inicializa objetos y establece el valor de los datos que se pasa al método en pruebas.

  • La sección Act invoca al método en pruebas con los parámetros organizados.

  • La sección Assert comprueba si la acción del método en pruebas se comporta de la forma prevista. Para .NET, los métodos de la clase Assert se usan a menudo para la comprobación.

Para probar el método CheckingAccount.Withdraw del ejemplo, podemos escribir dos pruebas: una que compruebe el comportamiento estándar del método y otra que compruebe si una retirada que supere el saldo producirá un error. (En el código siguiente se muestra una prueba unitaria MSTest, que se admite en .NET). En la clase CheckingAccountTests , agregamos los siguientes métodos:

[TestMethod]
public void Withdraw_ValidAmount_ChangesBalance()
{
    // arrange
    double currentBalance = 10.0;
    double withdrawal = 1.0;
    double expected = 9.0;
    var account = new CheckingAccount("JohnDoe", currentBalance);

    // act
    account.Withdraw(withdrawal);

    // assert
    Assert.AreEqual(expected, account.Balance);
}

[TestMethod]
public void Withdraw_AmountMoreThanBalance_Throws()
{
    // arrange
    var account = new CheckingAccount("John Doe", 10.0);

    // act and assert
    Assert.ThrowsException<System.ArgumentException>(() => account.Withdraw(20.0));
}

Para obtener más información sobre los marcos de pruebas unitarias de Microsoft, consulte uno de los temas siguientes:

Establecer tiempos de espera de conexión para las pruebas unitarias

Si usa el marco MSTest, puede usar TimeoutAttribute para establecer un tiempo de espera en un método de prueba individual:

[TestMethod]
[Timeout(2000)]  // Milliseconds
public void My_Test()
{ ...
}

Para establecer el tiempo de espera en el máximo permitido:

[TestMethod]
[Timeout(TestTimeout.Infinite)]  // Milliseconds
public void My_Test ()
{ ...
}

Ejecutar pruebas en Explorador de pruebas

Al compilar el proyecto de prueba, las pruebas aparecen en el Explorador de pruebas. Si el Explorador de pruebas no está visible, elija Prueba en el menú de Visual Studio, Ventanas y, después, Explorador de pruebas (o presione CTRL + E, T).

Unit Test Explorer

Unit Test Explorer

Al ejecutar, escribir y volver a ejecutar las pruebas, el Explorador de pruebas puede mostrar los resultados en grupos clasificados como Pruebas no superadas, Pruebas superadas, Pruebas omitidas y Pruebas no ejecutadas. En la barra de herramientas puede elegir diferentes opciones de agrupación.

También puede filtrar las pruebas en cualquier vista haciendo coincidir texto del cuadro de búsqueda a nivel global o seleccionando uno de los filtros predefinidos. Se puede ejecutar cualquier selección de las pruebas en cualquier momento. Los resultados de una serie de pruebas son inmediatamente visibles en la barra de éxito/error de la parte superior de la ventana del explorador. Los detalles de un resultado del método de prueba se muestran al seleccionar la prueba.

Ejecutar y ver las pruebas

La barra de herramientas del Explorador de pruebas le ayuda a detectar, organizar y ejecutar las pruebas que le interesan.

Run tests from the Test Explorer toolbar

Run tests from the Test Explorer toolbar

Puede elegir Ejecutar todas para ejecutar todas las pruebas (o presione CTRL + R, V), o bien Ejecutar para seleccionar el subconjunto de pruebas que quiere ejecutar (CTRL + R, T). Seleccione una prueba para ver sus detalles correspondientes en el panel Detalles de la prueba. Seleccione Abrir prueba en el menú contextual (teclado: F12) para mostrar el código fuente de la prueba seleccionada.

Si las pruebas individuales no tienen ninguna dependencia que impida que se ejecuten en cualquier orden, active la ejecución de pruebas paralelas en el menú de configuración de la barra de herramientas. Esto puede reducir considerablemente el tiempo necesario para ejecutar todas las pruebas.

Ejecutar pruebas después de cada compilación

Para ejecutar las pruebas unitarias después de cada compilación local, abra el icono de configuración en la barra de herramientas del Explorador de pruebas y seleccione Ejecutar pruebas después de compilar.

Filtrar y agrupar la lista de pruebas

Si tiene muchas pruebas, puede escribir en el cuadro de búsqueda del Explorador de pruebas para filtrar la lista por la cadena especificada. Para limitar aún más el evento de filtro, elija una opción de la lista de filtros.

Search filter categories

Search filter categories

Button Descripción
Test Explorer group button Para agrupar las pruebas por categoría, elija el botón Agrupar por .

Para obtener más información, consulte Ejecutar pruebas unitarias con el Explorador de pruebas.

Preguntas y respuestas

P: ¿Cómo puedo depurar las pruebas unitarias?

R: Use el Explorador de pruebas para iniciar una sesión de depuración de pruebas. La ejecución paso a paso del código con el depurador de Visual Studio permite avanzar y retroceder sin problemas entre las pruebas unitarias y el proyecto objeto de prueba. Para iniciar la depuración:

  1. En el editor de Visual Studio, establezca un punto de interrupción en uno o varios métodos de prueba que desee depurar.

    Nota

    Dado que los métodos de prueba se pueden ejecutar en cualquier orden, establezca puntos de interrupción en todos los métodos de prueba que desee depurar.

  2. En el Explorador de pruebas, seleccione los métodos de prueba y después elija Depurar pruebas seleccionadas en el menú contextual.

Obtenga más información sobre la depuración de pruebas unitarias.

P: Si uso TDD, ¿cómo puedo generar el código a partir de las pruebas?

R: Use Acciones rápidas para generar clases y métodos en el código del proyecto. Escriba una instrucción en un método de prueba que llame a la clase o al método que quiera generar y, después, abra la bombilla que aparece debajo del error. Si la llamada es a un constructor de la nueva clase, elija Generar tipo en el menú y siga el asistente para insertar la clase en el proyecto de código. Si la llamada es a un método, elija Generar método en el menú de IntelliSense.

Generate Method Stub Quick Action Menu

Generate Method Stub Quick Action Menu

P: ¿Puedo crear pruebas unitarias que usan varios conjuntos de datos como entrada para ejecutar la prueba?

R: Sí. Losmétodos de prueba controlados por datos permiten probar un intervalo de valores con un solo método de prueba unitaria. En el método de prueba, use un atributo DataRow, DynamicData o DataSource que especifique el origen de datos que contiene los valores de las variables que quiere probar.

El método con el atributo se ejecuta una vez para cada fila del origen de datos. El Explorador de pruebas notifica un error de prueba para el método si alguna de las iteraciones no se supera. El panel de detalles de los resultados de las pruebas para el método muestra el método de estado de éxito/error para cada fila de datos.

Más información sobre pruebas unitarias controladas por datos.

P: ¿Puedo ver la cantidad de código probado en las pruebas unitarias?

R: Sí. Con la herramienta de cobertura de código de Visual Studio se puede determinar la cantidad del código que las pruebas unitarias están probando realmente en Visual Studio Enterprise. Se admiten los lenguajes nativos y administrados, así como todos los marcos de pruebas unitarias que pueda ejecutar el Marco de pruebas unitarias.

La cobertura de código se puede ejecutar en pruebas seleccionadas o en todas las pruebas de una solución. La ventana Resultados de la cobertura de código muestra el porcentaje de bloques de código de producto que se han ejecutado por línea, función, clase, espacio de nombres y módulo.

Para ejecutar la cobertura de código con los métodos de prueba de una solución, elija Prueba>Analizar cobertura de código para todas las pruebas.

Los resultados de la cobertura aparecen en la ventana Resultados de la cobertura de código.

Code coverage results

Code coverage results

Obtenga más información sobre la cobertura de código.

P: ¿Puedo probar en el código métodos que tengan dependencias externas?

R: Sí. Si tiene Visual Studio Enterprise, Microsoft Fakes se puede emplear con los métodos de prueba que se escriben usando marcos de pruebas unitarias para código administrado.

Microsoft Fakes usa dos enfoques para crear las clases de sustitución de dependencias externas:

  1. Loscódigos auxiliares generan clases de sustitución derivadas de la interfaz primaria de la clase de dependencia de destino. Los métodos de código auxiliar se pueden sustituir por métodos virtuales públicos de la clase de destino.

  2. Lascorrecciones de compatibilidad (shim) usan la instrumentación del runtime para desviar las llamadas a un método de destino a un método shim de sustitución para métodos no virtuales.

En ambos enfoques, use los delegados generados de las llamadas al método de dependencia para especificar el comportamiento deseado en el método de prueba.

Más información sobre cómo aislar métodos de prueba unitaria con Microsoft Fakes.

P: ¿Puedo usar otros marcos de pruebas unitarias para crear pruebas unitarias?

A: Sí, siga estos pasos para buscar e instalar otros marcos. Después de reiniciar Visual Studio, vuelva a abrir la solución para crear las pruebas unitarias y seleccione los marcos instalados aquí:

Select other installed unit test framework

El código auxiliar de prueba unitaria se creará con el marco seleccionado.