Ir para o conteúdo principal
Background Image

Otimizando o ambiente de desenvolvimento para refatoração

··7 minutos·
Rafael Issao
Autor
Rafael Issao
Apaixonado por tecnologia, programação e inovação. Adoro compartilhar conhecimento e aprender coisas novas todos os dias.
Tabela de conteúdos

Introdução
#

Neste artigo, compartilho o que eu tenho implementado em projetos reais para melhorar o ambiente de desenvolvimento para facilitar as refatorações.

Utilizarei ferramentas como exemplo:

  • Gradle
  • Npm + Jest

Mas a ideia pode ser replicada para qualquer outra ferramenta.

Qualquer ferramenta que eu utilizo, sempre tento:

  • 🚦 Evitar multitarefa
  • 🕒 Obter feedback imediato e preciso
  • 🧹 Evitar coisas desnecessárias

Vamos configurar o gradle e npm + jest para para aplicar estes três itens no projeto!

🚦 Evitar multitarefa
#

Executar testes unitários é obrigatório para refatoração, mas lembrar de realizá-los a cada etapa da refatoração pode ser um ponto fraco. Posso facilmente esquecer e acabar dando um passo maior do que o necessário.

Para automatizar o processo de execução dos testes, podemos executar os seguintes comandos:

Comandos executados no terminal, na raiz do projeto
Comandos executados no terminal, na raiz do projeto

Ambos os comandos têm o objetivo de executar os testes ao observar mudanças no código de teste ou de produção.

Antes de refatorar o código, eu executo esse comando no terminal. Evito rodar na IDE para minimizar distrações no editor de código.

A execução dos testes está totalmente automatizada!


🔗 Para mais informações


🕒 Obter feedback imediato e preciso
#

Quando penso em feedback de testes, penso da seguinte forma:

  • Quando os testes passam, não preciso do log dos testes
  • Quando os testes falham, o log deve ser claro e fácil de ler, facilitando a identificação do que deu errado

Então pensei em notificações. Uma notificação com o resultado dos testes pode ser exibida:

  • Se for positivo, aguardo a notificação desaparecer e sigo com a refatoração.
  • Se houver algum erro, abro o log dos testes para investigar.

Implementei a notificação do resultado dos testes da seguinte forma no build.gradle:

Notificação que funciona no macos e ubuntu
Notificação que funciona no macos e ubuntu

A configuração acima suporta apenas macOS e Ubuntu, mas também é possível implementá-la no Windows utilizando o PowerShell!

E se puder, abuse de cores e emojis. Quando vejo uma notificação verde, já sei que os testes passaram. Nem preciso ler o texto!


🔗 Para mais informações - Gradle


O Jest já possui suporte nativo a notificações, funcionando em macOS, Linux e Windows. Para utilizá-lo, basta ter o módulo node-notifier instalado e configurá-lo adequadamente:

jest.config.js
jest.config.js

Com essas configurações, sempre que salvo um arquivo, os testes são executados e os resultados são reportados para mim por meio de notificações.

Quando um teste falha, eu analiso os logs com calma!


🔗 Para mais informações - Jest


Agora, vamos melhorar os logs dos testes.

Infelizmente, tanto no Gradle quanto no npm com Jest, os logs do resultado dos testes não são bons.

Vamos comparar como os logs ficam antes e depois da configuração que será explicada:

Melhorando gradle
Melhorando gradle
Melhorando Jest
Melhorando Jest

Configurar o gradle é simples.

Tem um plugin chamado test-logger e é só configurar no build.gradle:

// Example of build.gradle configuration for test-logger plugin
plugins {
    id 'java'
    id 'com.adarshr.test-logger' version '2.1.0'
}

testlogger {
    theme 'mocha'
    showExceptions true
    showStackTraces true
    showFullStackTraces false
    showStandardStreams true
    showPassed true
    showSkipped true
    showFailed true
    showSummary true
    showSimpleNames true
    showCauses true
    slowThreshold 2000
}

🔗 Para mais informações - Test logger


No Jest temos que fazer mais coisas.

O problema principal do Jest é que não é possível adicionar mensagens customizadas quando o teste falha.

Existe até um plugin para isso que é o jest-expect-message. Mas faz um tempo que não é atualizado.

O pessoal do jest parece não querer muito implementar custom messages também.

Logo, vou mostrar como criar um “matcher” personalizado, mas essa não é a solução ideal!

Talvez valha a pena observar como o autor do jest-expect-message fez e implementar uma solução parecida para sua equipe ou empresa.

Outra opção seria considerar o uso de uma ferramenta de teste diferente.

Vamos configurar o jest e npm então!

1️⃣ Primeiro passo é criar o arquivo jest.setup.js:

jest.setup.js
jest.setup.js

Este arquivo será responsável por criar uma nova função toEqualsWithMessage que aceita uma mensagem customizada.

2️⃣ Segundo passo é associar o jest.setup.js em jest.config.js:

jest.config.js
jest.config.js

Este arquivo será executado sempre antes de todos os testes. Ou seja,a função nova estará disponível para ser utilizado em todos os testes.

3️⃣ Terceiro passo é habilitar o auto-complete nas IDE criando o arquivo toequals.with.message.d.ts:

toequals.with.message.d.ts
toequals.with.message.d.ts

Este passo é importante para facilitar a criação dos testes. Mais especificamente habilitar o autocomplete nas IDEs.

4️⃣ Criar jsconfig ou tsconfig para associar o arquivo de declaração toequals.with.message.d.ts:

jsconfig.json
jsconfig.json

Este passo é crucial pois muitas IDEs utilizam o jsconfig ou tsconfig, por exemplo, para fazer autocomplete de linguagens como javascript e typescript.

E, finalmente, configuramos um custom matcher, com autocomplete na IDE, e que permite o uso de mensagens personalizadas!

É importante lembrar que essa não é a solução ideal!

Além de ser trabalhoso, teremos que implementar um custom matcher para cada novo matcher que utilizarmos.

E se atualizarmos o Jest e ocorrer alguma quebra de API, o esforço para atualizar todos os custom matchers e os arquivos relacionados pode ser grande.


🔗 Para mais informações - Jest


🧹 Evitar coisas desnecessárias
#

A última coisa que gosto de fazer é acelerar o ciclo de feedback, evitando esforços desnecessários.

Por exemplo, quando executamos testes no Gradle, são gerados arquivos HTML e XML para relatórios.

Esses relatórios não são necessários durante o ciclo de feedback voltado para refatoração.

Portanto, podemos desabilitá-los:

// Example of build.gradle configuration to disable test reports
test {
    reports.html.enabled = false
    reports.junitXml.enabled = false
}

No Jest, nenhum arquivo é gerado, portanto, não precisamos nos preocupar com isso.

Outra questão importante é que muitos projetos não têm configurações para diferenciar entre a execução de testes rápidos, como os unitários, e os testes mais lentos, como os de integração, e assim por diante.

Se você está nesta situação, a seguinte estratégia é recomendada:

  • 🔍 Revisar o código que será refatorado
  • ⚡ Identificar quais testes rápidos podem auxiliar na refatoração
  • 🏷️ Categorizar esses testes como unitários ou rápidos
  • 🛠️ Separar esses testes em configurações distintas no Gradle ou npm com Jest
  • ▶️ Executar continuamente apenas esses testes
  • 🚀 Configurar seu projeto para que, no ambiente de integração contínua, os testes rápidos sejam executados primeiro, seguidos pelos testes lentos

Com essa estratégia, você evita a necessidade de investigar todos os testes e vai separando gradualmente os testes rápidos e lentos conforme a necessidade.

Existem muitos artigos que podem ajudá-lo a categorizar os testes e a configurar o projeto:

Uma última coisa a lembrar é que essas configurações que fizemos devem ser aplicadas apenas no computador da equipe.

No ambiente de integração contínua, por exemplo, não faz sentido ter notificações, enquanto é importante ter relatórios em HTML, XML, de cobertura e assim por diante.

Para isso, podemos utilizar variáveis de ambiente:

Exemplo de build.gradle
Exemplo de build.gradle

Outra opção é criar scripts diferentes para cada ambiente. Por exemplo, no package.json, poderíamos ter:

Um script para ser executado localmente e outro para ser executado em CI
Um script para ser executado localmente e outro para ser executado em CI

Além disso, podemos criar um novo arquivo de configuração do Jest que desativa as notificações, mas habilita os relatórios necessários para o ambiente de CI.

jest.ci.config.js
jest.ci.config.js

Esses são alguns exemplos de como separar configurações e execuções de testes, otimizando o ambiente local para refatoração.


🔗 Para mais informações


Conclusão
#

Otimizar o processo de refatoração requer um entendimento mais profundo de como funcionam as ferramentas utilizadas pela equipe.

No entanto, quando conseguimos configurar um projeto dessa maneira, posso garantir que a refatoração se torna mais divertida e segura!

É importante ressaltar que o que compartilhei aqui não é a única forma de fazer as coisas.

Existem outras abordagens que podem ser ainda melhores, e sempre surgirão novas ideias à medida que as ferramentas evoluem.

Espero que este artigo tenha te inspirado a otimizar seu ambiente de trabalho, permitindo que você produza um código ainda melhor do que o que já escreve hoje!

Se você tiver dúvidas, sugestões ou até correções, sinta-se à vontade para comentar ou falar diretamente comigo!

🥒🥒 Até o próximo artigo! 🥒🥒