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:

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:

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:

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
- Notify do Jest
- rootDir config do Jest
- notifyMode config do Jest
- Exemplo de configuração do jest.config.js
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:


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:

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:

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:

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:

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
- Exemplo de jest.setup.js
- Exemplo de jest.config.js
- Exemplo de toequals.with.message.d.ts
- Exemplo de jsconfig.json
- ANSI Escape Sequences
🧹 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:
- https://www.baeldung.com/junit-filtering-tests
- https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html
- https://jestjs.io/docs/cli#–testnamepatternregex
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:

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

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.

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! 🥒🥒


