Componente testáveis e não testáveis no front-end:

Gleydson Jose
Mercafacil
Published in
8 min readFeb 24, 2022

Olá pessoal, tudo bem com vocês? Hoje eu venho compartilhar com vocês algumas dicas de como definir a prioridade em alguns tipos de componentes e criar testes a partir disso. Adicionar prioridades diferentes em componentes é crucial para manter ou criar testes saudáveis no front-end. Então vamos lá.

Uma mesa com um notebook, um caderno com caneta, uma xícara de café e uma bolsa.

Quando estamos começando a criar novo testes ou refatorando os já existentes acabam surgindo algumas dúvidas mais comuns:

1- Será que estou testando corretamente esse componente?

2- Esse componente vale a pena ser testado?

3- Será que testar isso aqui do componente é realmente importante?

4- Testar essa parte do componente vai ajudar em que futuramente?

São essas e várias outras dúvidas que podemos ter ao tentar testar algo no front-end, até porque não é algo tão comum e simples de ser feito.

Devido a complexidade dos eventos interativos no front-end, os testes precisam ser construídos com muita cautela. Como existem interações intrínsecas entre os componentes, muitas vezes é mais prudente a utilização de mocks para isolar apenas os componentes que desejamos testar.

Um dos objetivos desse artigo é te mostrar também que há certos componentes que não devemos dar uma prioridade alta no momento de testar, devemos separar cada um por prioridades específicas e até níveis de importância para o software que você está trabalhando. Com isso em mente, eu irei separar alguns componentes por apenas duas prioridades para os exemplos, a prioridade alta e baixa, vamos para alguns exemplos:

Alguns componentes de baixa prioridade:

1- Listas

2- Rodapés

3- Banners ou Headers de página

4- Componente que apenas usa componentes filhos para agrupar em um escopo maior.

- App.vue é um bom exemplo disso

- Também tem os layouts de páginas, aqueles componentes que sempre vão ser usados para manter breadcrumbs, filtros e outras coisas padrões numa página, mas dentro dele vai ter conteúdos dinâmicos que serão os filhos/children.

5- Componentes com imagens e textos estáticos

6- Tabelas

- Tabelas podem ter ordenação de colunas, paginação e até Drag & Drop de dados nas linhas ou colunas como se fossem uma planilha, então porque estou colocando uma prioridade baixa nesse tipo de componente? O motivo principal é que todas essas coisas citadas são possíveis de testar separadamente do componente.

- Ordenação de colunas provavelmente vai ser um método específico que ordena os dados e retorna tudo pronto para a tabela renderizar na tela, então ele pode ser um helper ou algo que vai ser reutilizado entre componentes parecidos.

- Paginação deve ser um componente específico para isso, onde nele vai ter toda a lógica para tratar a paginação de itens em um array recebido, então você não vai testar ele dentro da tabela e sim criar um teste específico para esse componente de paginação.

- Drag & Drop é outra coisa que vai ter helpers que podem ser reutilizados em vários componentes, então ele é algo compartilhável e não único da tabela, por isso deve ter testes apenas para ele.

Aqui foram apenas alguns exemplos básicos e provavelmente você percebeu que componentes que apenas recebem dados para mostrar na tela não devem ter uma prioridade alta de testes, mas não se engane achando que eles não podem ser testados, todos eles devem ter pelo menos um snapshot para garantir que estão renderizando corretamente o que é preciso renderizar, mas adicionar esse teste de snapshot ainda continua sendo de prioridade baixa, lembre-se disso.

Outro detalhe que você pode ter percebido também é que muita das coisas que um componente tem podem ser reutilizados por outros componentes e por isso você deve separar cada uma dessas coisas em helpers ou métodos auxiliares que podem ser compartilhados. Esse é o pensamento que eu quero que vocês tenham ao olhar para um componente e analisar cada linha de código antes de criar testes, ao fazer isso você vai perceber que as vezes devemos refatorar o componente e separar as responsabilidades dele para facilitar os testes e deixar o componente mais fácil de entender.

Alguns componentes de alta prioridade:

1- Componentes que tratem de uma regra crítica para o negócio

- Esse tipo de componente é crucial que funcione perfeitamente para o usuário, se não isso pode prejudica-lo e até fazer a empresa que em você trabalha perder dinheiro, por isso foque bastante em testar tudo que for importante para esse componente.

2- Componentes que tenham lógicas em métodos e até no template do componente

- Aqui devemos ter uma atenção grande nos testes de template, porque testes no template do componente devem focar, por exemplo naquelas condicionais que dependendo de uma condição específica será renderizado uma coisa ou outra, ou até se uma informação recebida do componente pai foi renderizada com sucesso em certas tags HTML e por fim até uma class HTML ou mensagem para indicar erro/sucesso de alguma coisa.

- Ainda falando de template, elementos como botões, inputs e outros que usam métodos após acionar algum evento devem ser testados, mas tenha em mente que ao acionar um evento, teste apenas se o método está sendo chamado ou não, não teste a lógica desse método após acionar um evento, trate ela como uma caixa preta e faça mocks se for necessário.

- Você pode testar métodos separadamente de um evento acionado no template, mas tente focar em métodos que tenham entrada/input e saída/output, métodos que fazem algum tipo de efeito colateral/side effects podem ser testados mas não devem ter uma prioridade tão alta, porque normalmente esses métodos vão modificar variáveis, estados/states de aplicações SPA e atributos de classes de orientação a objetos. Após testar esse tipo de método você vai ter que verificar o valor final desses elementos modificados, e claro que isso pode complicar futuramente porque todos esses elementos podem ser modificados por outros métodos no ciclo de vida da aplicação e acabar quebrando os testes.

- Métodos que chamam outros métodos podem ser testados, você deve verificar se esses outros métodos estão sendo chamados corretamente após acionar esse método principal e com isso você vai ter que mockar esses outros métodos ou até usar um spy para acompanhar se eles estão sendo utilizados.

3- Componentes que são dinâmicos.

- Aqueles componentes que mostram ou escondem algo após ações do usuário

4- Filtros

- Você pode testar a entrada e saída desse tipo de componente.

5- Campo de busca ou inputs de textos específicos

- Aqui você pode testar botões que interagem com esses componentes e até a lógica de limite de caracteres se caso existir, normalmente esses componentes tem várias funcionalidades para ajudar na usabilidade do usuário.

- Se o input for muito simples não tente dar uma prioridade alta para ele, um input de texto que apenas modifica uma variável/state/atributo e mais nada não deve ser priorizado,

Nesse momento você percebe que mesmo um componente de alta prioridade tem coisas de baixa prioridade para testar, por isso mais uma vez eu reforço que devemos analisar bem os componentes que queremos testar. Normalmente iniciamos os testes em coisas mais importantes nesse tipo de componente e futuramente vamos adicionando testes em coisas menos importantes.

Chegando até aqui também percebemos vários pontos importantes para se observar em um componente, e com isso vamos a alguns exemplos em scripts e imagens para reforçar um pouco o que foi citado no artigo.

Nesses exemplos irei utilizar o Vue 2 junto ao Jest e Vue-Test-Utils, mas todos esses pontos citados acima são aplicáveis para outros frameworks e bibliotecas.

Aqui temos um rodapé simples que é bastante utilizado em vários websites:

Rodapé de um site com texto de copyright e algumas redes sociais

Esse tipo de componente normalmente é usado apenas para mostrar algo e não tem nenhuma lógica especial e por isso ele é de baixa prioridade.

Vamos observar seu código:

Aqui podemos ver que ele não tem nada de especial para ser testado, mas lembre-se que ele pode ter pelo menos um teste de snapshot dessa forma:

Mas além desse tipo de componente simples há também o componente com um certo grau de complexidade e com lógicas específicas para seu funcionamento, então vamos usar um componente de campo de busca como exemplo aqui:

Campo de busca

Esse componente há um contador de caracteres que pode validar se há algum erro no campo:

Campo de busca com erro

Então ele já tem algo que é importante de ser testado e observado com mais cuidado.

Vamos dar uma olhada em seu script:

Podemos ver que esse componente há sim certa complexidade internamente e com isso em mente já podemos criar alguns testes pensando nisso.

Por exemplo, aqui estamos verificando se o input preenche o placeholder com o texto recebido por props:

Podemos também verificar se um evento está sendo acionado após clicar no botão para limpar o input:

As vezes conseguimos fazer o teste da versão positiva e negativa de alguma funcionalidade, por exemplo:

  • Verificar se o contador de caracteres é renderizado após uma condição:
  • Verificar se o contador de caracteres não é renderizado após uma condição:

E claro que não podemos esquecer do teste usando snapshot:

Por fim, podemos testar o retorno de métodos:

  • Deveria retornar o booleano false após uma condição:
  • Deveria retornar o booleano true após uma condição:
  • Deveria retornar uma mensagem de erro após uma condição:
  • Deveria retornar o texto do contador de caracteres após uma condição:

Com tudo isso, podemos observar que todo componente pode ser testado, mas o ponto importante aqui é definir a prioridade de cada um e ir focando em coisas mais cruciais para o funcionamento do software.

Para não me prolongar muito aqui nesse artigo, eu criei um pequeno projeto no GitHub com esses componentes utilizados nos exemplos acima e vários outros com seus respectivos testes. Por isso se caso você estiver interessado em ver mais exemplos dê uma olhada nesse projeto:

Espero que todos vocês tenham aprendido algo novo com esse artigo, meu objetivo aqui foi compartilhar com vocês um pouco de conhecimento de que venho adquirindo com o passar do tempo. Muito obrigado pessoal e bons testes.

--

--