Angular

21 jan, 2026

Angular v21 e o Fim da Cobertura de Testes Exclusivamente em TypeScript: Por Que Precisamos Repensar os Testes de Componentes

Publicidade

Neste artigo, vamos explorar uma mudança significativa no Angular v21 que afeta a forma como testamos nossos componentes. O Angular v21 introduz o Vitest como a biblioteca de testes padrão, substituindo a antiga configuração Jasmine/Karma. Embora isso possa parecer apenas uma atualização de ferramentas, tem implicações profundas para nossas estratégias de teste.

A verdadeira mudança reside na adequação às diretrizes de estilo modernas do Angular, no encapsulamento apropriado e na cobertura de testes precisa.

Se você atualizou recentemente para o Angular v21 (ou migrou para o Vitest) e de repente notou lacunas de cobertura que não existiam antes, não se preocupe. Vamos explorar por que isso está acontecendo e como adaptar seus testes para atender às expectativas do Angular.

Este é um artigo de opinião sobre os próximos passos nos testes com Angular v21+.

O Modelo Mental Legado: Cobertura Exclusiva de TypeScript

Durante muito tempo, os aplicativos Angular foram testados usando:

  • Jasmim + Karma
  • Configurações baseadas em Jest

Independentemente do executor, a cobertura era efetivamente exclusiva do TypeScript :

  • .tsos arquivos foram instrumentados
  • .htmlOs modelos geralmente eram ignorados.

espaço reservado

Isso levou a um padrão de teste comum, no qual os desenvolvedores costumavam:

  • Chame os métodos dos componentes diretamente (já que eles eram públicos).
  • Ler ou modificar propriedades de componentes em testes (já que eram públicas)
  • Afirmar sobre o estado interno

Enquanto o método fosse executado, a cobertura aumentava, mesmo que o modelo nunca exercesse essa lógica .

O resultado? Altas métricas de cobertura que pareciam ótimas no papel, mas não refletiam com precisão a confiabilidade da interface do usuário.

Angular v21 + Vitest: Os modelos agora fazem parte da cobertura de testes.

O Angular v21 altera a configuração de teste padrão para Vitest . A mudança mais significativa está na forma como a cobertura é relatada:

Os modelos HTML agora estão incluídos nos relatórios de cobertura.

espaço reservado

O que isso significa na prática? A cobertura agora inclui:

  • Associações de eventos como (click)e(change)
  • Renderização condicional ( @ife outros controles)
  • Diretrizes estruturais
  • Caminhos de execução orientados por modelos

Como resultado:

  • Chamar um método de componente diretamente não “encobre” mais a lógica do template.
  • Agora, as lacunas de cobertura aparecem exatamente onde a interface do usuário não está sendo utilizada.

Isso não é uma regressão. É o Angular fornecendo uma visão mais precisa e honesta da saúde da sua aplicação.

O impacto dos membros protegidos

Desde a versão 20 do Angular, o guia de estilo do Angular recomenda:

Dê preferência ao acesso protegido para quaisquer membros que devam ser lidos a partir do modelo do componente.

Isso adiciona mais um desafio à abordagem de teste legada. Se um membro for `null` protected, ele não estará acessível no seu arquivo de teste. Você não pode simplesmente acessar o componente e verificar uma propriedade ou chamar um método diretamente.

O que isso significa? Mesmo que você quisesse ignorar o modelo e testar a lógica diretamente, o TypeScript não permitiria.

Portanto, temos duas forças nos impulsionando na mesma direção:

  1. O Vitest requer a execução de um modelo para cobertura.
  2. O Guia de Estilo do Angular restringe o acesso à lógica interna dos componentes.

A mensagem é clara: pare de testar detalhes de implementação. Comece a testar o comportamento.

Um exemplo real: componente ProductListComponent

Para ilustrar isso, vejamos um exemplo real. O ProductListComponentexemplo do meu modern-angularrepositório demonstra esse padrão:

app/products/product-list

Este componente foi projetado seguindo os padrões modernos do Angular:

  • Lógica orientada a modelos : O modelo gerencia as interações do usuário.
  • Membros protegidos : Propriedades e métodos usados ​​apenas no modelo são marcados comoprotected
  • API pública mínima : O componente expõe apenas o que é estritamente necessário.

Este design segue as recomendações que o guia de estilo do Angular vem incentivando desde a versão 20.

Padrão de teste legado (pré-v21)

Antes do Angular v21, um teste típico geralmente se parecia com isto:

it('filters products by category', () => {
  component.selectedCategory = 'Books';
  component.applyFilter();

  expect(component.filteredProducts.length).toBe(2);
});

Por que isso pareceu correto?

  • O método foi executado com sucesso.
  • As afirmações foram aprovadas.
  • As métricas de cobertura do TypeScript aumentaram.

No entanto, eis o que realmente aconteceu:

  • O modelo nunca esteve envolvido no teste.
  • Nenhuma interação do usuário (clique, entrada de dados, etc.) foi simulada.
  • O teste validou detalhes da implementação, não o comportamento real.

Com o Vitest, a cobertura de HTML permanece intacta e os relatórios de cobertura revelam a verdade: o componente não foi totalmente testado .

O desafio: APIs protegidas não são fáceis de testar.

Em componentes Angular modernos:

  • Propriedades e métodos exclusivos do modelo são marcados com protected.
  • O TypeScript impede corretamente o acesso direto a esses membros a partir dos testes.

Isso cria atrito para estilos de teste legados. Soluções alternativas comuns incluem:

  • Convertendo o componente para any.
  • Métodos de criação criados publicexclusivamente para fins de teste.

Mas, com a cobertura que leva em consideração os modelos, essas soluções alternativas falham por dois motivos:

  1. Eles violam os princípios de encapsulamento.
  2. Eles não melhoram a cobertura do modelo.

O Angular está basicamente nos dizendo: se o seu teste não passar pelo modelo, ele não conta.

A solução: Teste através do modelo

A solução não é lutar contra o framework, mas sim mudar a forma como testamos os componentes .

Em vez de invocar a lógica diretamente, devemos:

  • Interagir com o DOM
  • Eventos de gatilho
  • Verifique a saída renderizada

Vamos refatorar o teste anterior para seguir esta abordagem:

it('filters products when a category is selected', async () => {
  const select = fixture.nativeElement.querySelector('select');

  select.value = 'Books';
  select.dispatchEvent(new Event('change'));
  fixture.detectChanges();

  const items = fixture.nativeElement.querySelectorAll('.product-item');
  expect(items.length).toBe(2);
});

O que está acontecendo aqui?

  • A interação de teste começa com o modelo (como os usuários realmente usam seu aplicativo).
  • A lógica protegida permanece protegida (encapsulamento adequado).
  • A cobertura agora inclui TypeScript e HTML.

Este teste reflete como os usuários realmente interagem com o componente, garantindo uma aplicação mais robusta e confiável.

💡 Bônus : Você obtém cobertura de testes tanto para o modelo HTML quanto para o código TypeScript dentro do componente!

Que mudanças ocorrem na prática?

Com o Angular v21+, seus testes devem:

  • Prefira a interação com o DOM em vez de chamadas de método.
  • Afirme o comportamento visível , não o estado interno.
  • Considere o modelo como o ponto de entrada.

O que você ganhará com essa mudança:

  • Os testes tornam-se mais fáceis de refatorar.
  • O encapsulamento melhora naturalmente
  • Os números de cobertura finalmente refletem o uso real.

Isso está perfeitamente alinhado com a direção de design do Angular e com as melhores práticas modernas de teste.

Conclusão

Ao atualizar para o Angular v21 + Vitest, espere o seguinte:

  • Observe a queda na cobertura em componentes com uso intensivo de interface do usuário.
  • Identifique testes que exercitem apenas a lógica TS.
  • Reescreva os testes para acionar o comportamento por meio do modelo assim que você tornar as propriedades e os métodos protegidos.

Cobertura de versões pré-Angular v21 com Jest:

espaço reservado

Angular v21 com Vitest:

espaço reservado

Inicialmente, essa mudança parece desconfortável. Mas, na realidade, o Angular v21 está fazendo algo importante:

  • Alinhar as diretrizes de estilo com as ferramentas.
  • Incentivar testes baseados no comportamento
  • Eliminando a falsa confiança da cobertura exclusiva de TS

O Angular não está tornando os testes mais difíceis. Está tornando os testes mais honestos .

Boa programação!