Condividi tramite


Testare i componenti Razor in ASP.NET Core Blazor

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Di Egil Hansen

Il test dei componenti Razor è un aspetto importante per il rilascio di app stabili e mantenibili Blazor.

Per testare un Razor componente, il componente sottoposto a test (CUT) è:

  • Reso con l'input pertinente per il test.
  • A seconda del tipo di test eseguito, eventualmente soggetto all'interazione o alla modifica. Ad esempio, i gestori eventi possono essere attivati, ad esempio un onclick evento per un pulsante.
  • Si è verificata la presenza di valori attesi. Un test viene superato quando uno o più valori controllati corrispondono ai valori previsti per il test.

Approcci di test

Due approcci comuni per i componenti di test Razor sono test end-to-end (E2E) e unit test:

  • Unit test: gli unit test vengono scritti con una libreria di unit test che fornisce:

    • Rendering dei componenti.
    • Ispezione dell'output e dello stato dei componenti.
    • Attivazione di gestori eventi e metodi del ciclo di vita.
    • Asserzioni che il comportamento del componente è corretto.

    bUnit è un esempio di libreria che consente Razor l'esecuzione di unit test dei componenti.

  • Test E2E: un test runner esegue un'app Blazor contenente CUT e automatizza un'istanza del browser. Lo strumento di test controlla e interagisce con CUT tramite il browser. Playwright per .NET è un esempio di framework di test E2E che può essere usato con Blazor le app.

Nel test unitario, solo il componente Razor (Razor/C#) è coinvolto. Le dipendenze esterne, ad esempio i servizi e JS l'interoperabilità, devono essere simulate. Nei test E2E, il Razor componente e tutta l'infrastruttura ausiliaria fanno parte del test, inclusi CSS, JSe le API DOM e browser.

Ambito di test descrive l'estensione dei test. L'ambito di test ha in genere un'influenza sulla velocità dei test. Gli unit test vengono eseguiti in un subset dei sottosistemi dell'app e in genere vengono eseguiti in millisecondi. Il completamento dei test E2E, che testano un ampio gruppo di sottosistemi dell'app, può richiedere alcuni secondi.

Il test unitario fornisce anche l'accesso all'istanza del CUT, consentendo l'ispezione e la verifica dello stato interno del componente. Questo in genere non è possibile nei test E2E.

Per quanto riguarda l'ambiente del componente, i test E2E devono assicurarsi che lo stato ambientale previsto sia stato raggiunto prima dell'avvio della verifica. In caso contrario, il risultato è imprevedibile. Negli unit test, il rendering di CUT e il ciclo di vita del test sono più integrati, migliorando così la stabilità dei test.

I test E2E comportano l'avvio di più processi, operazioni di I/O di rete e disco e altre attività del sottosistema che spesso causano una scarsa affidabilità dei test. Gli unit test sono in genere isolati da questi tipi di problemi.

La tabella seguente riepiloga la differenza tra i due approcci di test.

Capacità Test unitario Test E2E
Ambito di test Razor componente solo (Razor/C#) Razor componente (Razor/C#) con CSS/JS
Tempo di esecuzione dei test Millisecondi Secondi
Accesso all'istanza del componente No
Sensibile all'ambiente No
Affidabilità Più affidabile Meno affidabile

Scegliere l'approccio di test più appropriato

Si consideri lo scenario quando si sceglie il tipo di test da eseguire. Alcune considerazioni sono descritte nella tabella seguente.

Scenario Approccio suggerito Osservazioni:
Componente senza JS logica di interoperabilità Test unitario Quando un componente non dipende dall'interoperabilità JS, può essere testato senza accedere all'API JS o al DOM. In questo scenario non esistono svantaggi nella scelta degli unit test.
Componente con logica di interoperabilità semplice JS Test unitario È comune che i componenti eseguano query sul DOM o attivino animazioni tramite l'interoperabilità JS. Gli unit test sono in genere preferiti in questo scenario, perché è semplice simulare l'interazione JS tramite l'interfaccia IJSRuntime .
Componente che dipende da codice complesso JS Test unitari e separati JS Se un componente usa JS l'interoperabilità per chiamare una libreria di grandi dimensioni o complessaJS, ma l'interazione tra il componente e Razor la JS libreria è semplice, è probabile che l'approccio migliore consideri il componente e JS la libreria o il codice come due parti separate e testarne ognuna singolarmente. Testare il componente Razor con una libreria di unità di test e il JS con una libreria di test JS.
Componente con logica che dipende dalla JS manipolazione del DOM del browser Test E2E Quando la funzionalità di un componente dipende da JS e dalla manipolazione del DOM, verifica insieme il codice di JS e Blazor in un test E2E. Questo è l'approccio che gli sviluppatori del framework Blazor hanno adottato con la logica di rendering del browser di Blazor, che presenta una stretta integrazione tra il codice C# e JS. C# e il codice JS devono funzionare insieme per renderizzare correttamente i componenti Razor in un browser.
Componente che dipende da una libreria di classi di terze parti con dipendenze difficili da simulare Test E2E Quando la funzionalità di un componente dipende da una libreria di classi di terze parti con dipendenze difficili da simulare, come i componenti interoperabili JS, il test end-to-end potrebbe essere l'unica opzione per verificare il componente.

Componenti di test con bUnit

Non esiste un framework di test Microsoft ufficiale per Blazor, ma il progetto basato sulla community bUnit offre un modo pratico per eseguire unit test Razor dei componenti.

Nota

bUnit è una libreria di test di terze parti e non è supportata o gestita da Microsoft.

bUnit funziona con framework di test per utilizzo generico, ad esempio MSTest, NUnit e xUnit. Questi framework di test rendono i test bUnit simili ai normali unit test. I test bUnit integrati con un framework di test per utilizzo generico vengono eseguiti normalmente con:

Nota

I concetti di test e le implementazioni di test in framework di test diversi sono simili ma non identici. Per indicazioni, vedere la documentazione del framework di test.

Di seguito viene illustrata la struttura di un test bUnit sul Counter componente in un'app basata su un Blazor modello di progetto. Il Counter componente visualizza e incrementa un contatore in base all'utente che seleziona un pulsante nella pagina:

@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++;
    }
}

Il test bUnit seguente verifica che il contatore di CUT venga incrementato correttamente quando il pulsante è selezionato:

@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");
    }
}

I test possono essere scritti anche in un file di classe 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");
    }
}

In ogni passaggio del test vengono eseguite le azioni seguenti:

  • Arrange: Il componente Counter viene reso utilizzando bUnit TestContext. L'elemento paragrafo CUT (<p>) viene identificato e assegnato a paraElm. Nella sintassi Razor, un componente può essere passato come RenderFragment a bUnit.

  • Azione: l'elemento del pulsante (<button>) si trova e viene selezionato chiamando Click, che deve incrementare il contatore e aggiornare il contenuto del tag di paragrafo (<p>). Il contenuto del testo dell'elemento di paragrafo viene ottenuto chiamando TextContent.

  • Assert: MarkupMatches viene chiamato sul contenuto di testo per verificare che corrisponda alla stringa prevista, ovvero Current count: 1.

Nota

Il MarkupMatches metodo assert differisce da un'asserzione di confronto di stringhe regolare , ad esempio Assert.Equal("Current count: 1", paraElmText);. MarkupMatches esegue un confronto semantico dell'input e del markup HTML previsto. Un confronto semantico è consapevole della semantica HTML, ovvero gli spazi vuoti insignificanti vengono ignorati. In questo modo si ottengono test più stabili. Per altre informazioni, vedere Personalizzazione del confronto HTML semantico.

Risorse aggiuntive