Testar componentes do Razor no ASP.NET Core Blazor
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Essa versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Por Egil Hansen
O teste de componentes do Razor é um aspecto importante do lançamento de aplicativos Blazor estáveis e passíveis de manutenção.
Para testar um componente do Razor, o componente do em teste (CUT) é:
- Renderizado com entrada relevante para o teste.
- Dependendo do tipo de teste executado, possivelmente sujeito à interação ou modificação. Por exemplo, manipuladores de eventos podem ser disparados, como um evento
onclick
para um botão. - Inspecionado quanto aos valores esperados. Um teste é aprovado quando um ou mais valores inspecionados correspondem aos valores esperados para o teste.
Abordagens de teste
Duas abordagens comuns para componentes de teste Razor são teste de ponta a ponta (E2E) e teste de unidade:
Teste de unidade: os testes de unidade são gravados com uma biblioteca de testes de unidade que fornece:
- Renderização de componente.
- Inspeção da saída e do estado do componente.
- Acionamento de manipuladores de eventos e métodos de ciclo de vida.
- Declarações de que o comportamento do componente está correto.
bUnit é um exemplo de uma biblioteca que habilita o teste de unidade de componente do Razor.
Teste E2E: um executor de teste executa um aplicativo Blazor que contém a CUT e automatiza uma instância do navegador. A ferramenta de teste inspeciona e interage com o CUT por meio do navegador. Playwright para .NET é um exemplo de uma estrutura de teste E2E que pode ser usada com aplicativos Blazor.
No teste de unidade, somente o componente do Razor (Razor/C#) está envolvido. Dependências externas, como serviços e interoperabilidade JS, devem ser simuladas. No teste do E2E, o componente do Razor e toda a infraestrutura auxiliar fazem parte do teste, incluindo CSS, JS e as APIs do DOM e do navegador.
O escopo do teste descreve a extensão dos testes. O escopo de teste normalmente tem uma influência na velocidade dos testes. Os testes de unidade são executados em um subconjunto dos subsistemas do aplicativo e geralmente são executados em milissegundos. Os testes E2E, que testam um amplo grupo de subsistemas do aplicativo, podem levar vários segundos para serem concluídos.
O teste de unidade também fornece acesso à instância do CUT, permitindo a inspeção e a verificação do estado interno do componente. Normalmente, isso não é possível no teste do E2E.
Em relação ao ambiente do componente, os testes E2E devem garantir que o estado ambiental esperado tenha sido atingido antes do início da verificação. Caso contrário, o resultado será imprevisível. No teste de unidade, a renderização do CUT e o ciclo de vida do teste são mais integrados, o que melhora a estabilidade do teste.
O teste E2E envolve a inicialização de vários processos, E/S de rede e disco e outras atividades de subsistema que geralmente levam à baixa confiabilidade do teste. Os testes de unidade normalmente são isolados desses tipos de problemas.
A tabela a seguir resume as diferenças entre as duas.
Recurso | Teste de unidade | Teste E2E |
---|---|---|
Escopo de teste | Somente componente Razor (Razor/C#) | Componente do Razor (Razor/C#) com CSS/JS |
Tempo de execução do teste | Milissegundos | Segundos |
Acesso à instância do componente | Sim | Não |
Sensível ao ambiente | Não | Sim |
Confiabilidade | Mais confiável | Menos confiável |
Escolha a abordagem de teste mais apropriada
Considere o cenário ao escolher o tipo de teste a ser executado. Algumas considerações são descritas na tabela a seguir.
Cenário | Abordagem sugerida | Comentários |
---|---|---|
Componente sem lógica de interoperabilidade JS | Teste de unidade | Quando não há dependência de interoperabilidade JS em um componente Razor, o componente pode ser testado sem acesso a JS ou à API do DOM. Nesse cenário, não há desvantagens na escolha do teste de unidade. |
Componente com lógica de interoperabilidade simples JS | Teste de unidade | É comum que os componentes consultem o DOM ou disparem animações por meio da interoperabilidade JS. O teste de unidade geralmente é preferido nesse cenário, pois é simples simular a interação de JS por meio da interface IJSRuntime. |
Componente que depende de código complexo JS | Teste de unidade e teste separado JS | Se um componente usa JS interoperabilidade para chamar uma biblioteca JS grande ou complexa, mas a interação entre o componente Razor e a biblioteca JS é simples, é provável que a melhor abordagem trate o componente e a biblioteca JS ou o código como duas partes separadas e teste cada uma individualmente. Teste o componente do Razor com uma biblioteca de teste de unidade e teste o JS com uma biblioteca de testes JS. |
Componente com lógica que depende da manipulação JS do DOM do navegador | Teste E2E | Quando a funcionalidade de um componente depender de JS e de sua manipulação do DOM, verifique os códigos JS e Blazor em conjunto em um teste E2E. Essa é a abordagem que os desenvolvedores da estrutura de Blazor tomaram com a lógica de renderização do navegador Blazor, que tem C# e código JS firmemente acoplados. Os códigos C# e JS devem trabalhar juntos para renderizar corretamente os componentes do Razor em um navegador. |
Componente que depende da biblioteca de classes de terceiros com dependências difíceis de simular | Teste E2E | Quando a funcionalidade de um componente depende de uma biblioteca de classes de terceiros que tem dependências difíceis de simular, como interoperabilidade JS, o teste E2E pode ser a única opção para testar o componente. |
Testar componentes com bUnit
Não há nenhuma estrutura oficial de teste da Microsoft para Blazor, mas o projeto orientado pela comunidade bUnit fornece uma maneira conveniente de unidade de componentes de teste Razor .
Observação
bUnit é uma biblioteca de testes de terceiros e não tem suporte ou é mantida pela Microsoft.
o bUnit funciona com estruturas de teste de uso geral, como MSTest, NUnit e xUnit. Essas estruturas de teste fazem com que os testes bUnit se pareçam com testes de unidade regulares. Os testes bUnit integrados a uma estrutura de teste de uso geral normalmente são executados com:
- Explorer de teste do Visual Studio.
dotnet test
Comando da CLI em um shell de comando.- Um pipeline de teste de DevOps automatizado.
Observação
Os conceitos de teste e as implementações de teste em diferentes estruturas de teste são semelhantes, mas não idênticos. Confira a documentação da estrutura de teste para obter diretrizes.
A seguir, demonstra a estrutura de um teste bUnit no componente do Counter
em um aplicativo com base em um Blazor modelo de projeto . O componente do Counter
exibe e incrementa um contador com base no usuário selecionando um botão na página:
@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++;
}
}
O teste bUnit a seguir verifica se o contador cut é incrementado corretamente quando o botão é selecionado:
@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");
}
}
Os testes também podem ser escritos em um arquivo de 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");
}
}
As seguintes ações ocorrem em cada etapa do teste:
Organizar: o componente do
Counter
é renderizado usando o bUnit.TestContext
O elemento de parágrafo CUT (<p>
) é encontrado e atribuído aparaElm
. Em sintaxe Razor, um componente pode ser passado como um RenderFragment para bUnit.Agir: o elemento do botão (
<button>
) é localizado e, em seguida, selecionado chamandoClick
, que deve incrementar o contador e atualizar o conteúdo da marca de parágrafo (<p>
). O conteúdo do texto do elemento paragraph é obtido chamandoTextContent
.Assert:
MarkupMatches
é chamado no conteúdo do texto para verificar se ele corresponde à cadeia de caracteres esperada, que éCurrent count: 1
.
Observação
O método de declaração MarkupMatches
difere de uma declaração de comparação de cadeia de caracteres regular (por exemplo, Assert.Equal("Current count: 1", paraElmText);
). MarkupMatches
executa uma comparação semântica da marcação HTML esperada e de entrada. Uma comparação semântica está ciente da semântica HTML, o que significa que coisas como espaço em branco insignificante são ignoradas. Isso resulta em testes mais estáveis. Para saber mais, confira Personalização da comparação HTML semântica.
Recursos adicionais
- Introdução com bUnit: as instruções bUnit incluem diretrizes sobre como criar um projeto de teste, referenciar pacotes de estrutura de teste e criar e executar testes.
- Como criar componentes Blazor passíveis de manutenção e testáveis – Egil Hansen – NDC Oslo 2022