Compartir a través de


Prueba de componentes Razor en Blazor de ASP.NET Core

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

Por Egil Hansen

Las pruebas de componentes Razor son un aspecto importante de la publicación de aplicaciones Blazor estables y fáciles de mantener.

Para probar un componente Razor, el componente en prueba (CUT):

  • Se representa con la entrada pertinente para la prueba.
  • Depende del tipo de prueba que se realice, posiblemente sujeto a interacción o modificación. Por ejemplo, se pueden desencadenar controladores de eventos, como un evento onclick para un botón.
  • Se inspecciona en busca de los valores esperados. Una prueba se supera cuando uno o varios valores inspeccionados coinciden con los valores esperados para la prueba.

Enfoques de prueba

Dos enfoques habituales para probar componentes de Razor son las pruebas de un extremo a otro (E2E) y las pruebas unitarias:

  • Pruebas unitarias: las pruebas unitarias se escriben con una biblioteca de pruebas unitarias que proporciona lo siguiente:

    • Representación de componentes.
    • Inspección del estado y la salida del componente.
    • Desencadenamiento de controladores de eventos y métodos de ciclo de vida.
    • Aserciones del comportamiento correcto del componente.

    bUnit es un ejemplo de una biblioteca que permite realizar pruebas unitarias de componentes de Razor.

  • Pruebas de E2E: un ejecutor de pruebas ejecuta una aplicación Blazor que contiene el CUT y automatiza una instancia del explorador. La herramienta de pruebas inspecciona el CUT e interactúa con él a través del explorador. Playwright for .NET es un ejemplo de un marco de pruebas de E2E que se puede usar con aplicaciones Blazor.

En las pruebas unitarias, solo está implicado el componente de Razor (Razor/C#). Las dependencias externas, como los servicios y la interoperabilidad de JS, deben ser ficticias. En las pruebas de E2E, el componente de Razor y toda su infraestructura auxiliar forman parte de la prueba, incluidos CSS, JS y el DOM y las API del explorador.

El ámbito de la prueba describe el alcance de las pruebas. El ámbito de la prueba suele influir en la velocidad de las pruebas. Las pruebas unitarias se ejecutan en un subconjunto de los subsistemas de la aplicación, normalmente en cuestión de milisegundos. Las pruebas de E2E, que prueban un grupo amplio de los subsistemas de la aplicación, pueden tardar varios segundos en completarse.

Las pruebas unitarias también proporcionan acceso a la instancia del CUT, lo que permite inspeccionar y comprobar el estado interno del componente. Normalmente, esto no es posible en las pruebas de E2E.

Con respecto al entorno del componente, las pruebas de E2E deben asegurarse de que se ha alcanzado el estado del entorno esperado antes de que se inicie la comprobación. De lo contrario, el resultado es impredecible. En las pruebas unitarias, la representación del CUT y del ciclo de vida de la prueba están más integrados, lo que mejora la estabilidad de la prueba.

Las pruebas de E2E implican el inicio de varios procesos, la E/S de red y de disco, y otras actividades del subsistema que, a menudo, generan una mala confiabilidad de las pruebas. Normalmente, las pruebas unitarias se aíslan de estos tipos de problemas.

En la tabla siguiente se resumen las diferencias entre los dos enfoques de prueba.

Capacidad Pruebas unitarias Pruebas de E2E
Ámbito de la prueba Solo el componente de Razor (Razor/C#) El componente de Razor (Razor/C#) con CSS/JS
Tiempo de ejecución de la prueba Milisegundos Segundos
Acceso a la instancia del componente No
Sensible al entorno No
Confiabilidad Más confiable Menos confiable

Elección del enfoque de prueba más adecuado

A la hora de elegir el tipo de prueba que se va a realizar, tenga en cuenta el escenario. En la tabla siguiente se describen algunas consideraciones.

Escenario Enfoque sugerido Observaciones
Componente sin lógica de interoperabilidad de JS Pruebas unitarias Cuando no hay ninguna dependencia de la interoperabilidad de JS en un componente de Razor, el componente se puede probar sin acceso a JS ni a la API de DOM. En este escenario, la elección de pruebas unitarias no supone ninguna desventaja.
Componente con lógica de interoperabilidad de JS simple Pruebas unitarias Es habitual que los componentes consulten las animaciones el DOM o que desencadenen animaciones través de la interoperabilidad de JS. En este escenario normalmente se prefieren las pruebas unitarias, ya que resulta sencillo simular la interacción de JS a través de la interfaz IJSRuntime.
Componente que depende de código de JS complejo Pruebas unitarias y pruebas de JS independientes Si un componente usa la interoperabilidad deJS para llamar a una biblioteca de JS grande o compleja, pero la interacción entre el componente de Razor y la biblioteca de JS es sencilla, es probable que el mejor enfoque sea tratar el componente y la biblioteca o el código de JS como dos elementos independientes y probarlos de forma individual. Pruebe el componente de Razor con una biblioteca de pruebas unitarias y JS con una biblioteca de pruebas de JS.
Componente con lógica que depende de la manipulación de JS del DOM del explorador Pruebas de E2E Cuando la funcionalidad de un componente depende de JS y su manipulación del DOM, compruebe JS y el código de Blazor conjuntamente en una prueba de E2E. Este es el enfoque que los desarrolladores del marco Blazor han adoptado con la lógica de representación del explorador de Blazor, que tiene código de C# y JS estrechamente acoplado. El código de C# y JS debe trabajar de forma conjunta para representar correctamente componentes de Razor en un explorador.
Componente que depende de una biblioteca de clases de terceros con dependencias difíciles de simular Pruebas de E2E Cuando la funcionalidad de un componente depende de una biblioteca de clases de terceros con dependencias difíciles de simular, como la interoperabilidad de JS, la prueba de E2E podría ser la única opción para probar el componente.

Prueba de componentes con bUnit

No hay ningún marco de pruebas oficial de Microsoft para Blazor, pero el proyecto controlado por la comunidad bUnit proporciona una manera cómoda de realizar pruebas unitarias de componentes de Razor.

Nota

bUnit es una biblioteca de pruebas de terceros y no es compatible con Microsoft, que tampoco la mantiene.

bUnit funciona con marcos de pruebas de uso general, como MSTest, NUnit y xUnit. Estos marcos de pruebas hacen que las pruebas de bUnit parezcan pruebas unitarias normales. Las pruebas de bUnit integradas con un marco de pruebas de uso general normalmente se ejecutan con:

Nota

Los conceptos y las implementaciones de prueba de diferentes marcos de pruebas son similares, pero no idénticos. Consulte la documentación del marco de pruebas para obtener instrucciones.

A continuación se muestra la estructura de una prueba de bUnit en el componente Counter en una aplicación basada en una plantilla de proyecto de Blazor. El componente Counter muestra e incrementa un contador en función de la selección de un botón en la página por parte del usuario:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

La prueba de bUnit siguiente comprueba que el contador del CUT se incrementa correctamente cuando se selecciona el botón:

@code {
    [Fact]
    public void CounterShouldIncrementWhenClicked()
    {
        // Arrange
        using var ctx = new TestContext();
        var cut = ctx.Render(@<Counter />);
        var paraElm = cut.Find("p");

        // Act
        cut.Find("button").Click();

        // Assert
        var paraElmText = paraElm.TextContent;
        paraElm.MarkupMatches("Current count: 1");
    }
}

Las pruebas también se pueden escribir en un archivo de clase de C#:

public class CounterTests
{
    [Fact]
    public void CounterShouldIncrementWhenClicked()
    {
        // Arrange
        using var ctx = new TestContext();
        var cut = ctx.RenderComponent<Counter>();
        var paraElm = cut.Find("p");

        // Act
        cut.Find("button").Click();

        // Assert
        var paraElmText = paraElm.TextContent;
        paraElmText.MarkupMatches("Current count: 1");
    }
}

En cada paso de la prueba tienen lugar las acciones siguientes:

  • Organización: el componente Counter se representa mediante el objeto TestContext de bUnit. Se encuentra el elemento de párrafo del CUT (<p>) y se asigna a paraElm. En la sintaxis Razor, se puede pasar un componente como RenderFragment a bUnit.

  • Acción: se encuentra el elemento de botón (<button>) y se selecciona mediante una llamada a Click, que debe incrementar el contador y actualizar el contenido de la etiqueta de párrafo (<p>). El contenido textual del elemento de párrafo se obtiene mediante una llamada a TextContent.

  • Aserción: se llama a MarkupMatches en el contenido textual para comprobar que coincide con la cadena esperada, que es Current count: 1.

Nota:

El método Assert MarkupMatches difiere de una instrucción de aserción de comparación de cadenas normal (por ejemplo, Assert.Equal("Current count: 1", paraElmText);). MarkupMatches realiza una comparación semántica de la entrada y el marcado HTML esperado. Una comparación semántica tiene en cuenta la semántica de HTML, lo que significa que se omiten elementos como un espacio en blanco insignificante. Esto genera pruebas más estables. Para obtener más información, vea Personalización de la comparación HTML semántica.

Recursos adicionales