O que você precisa saber antes de construir um processo eficaz de Code Review
TEMPO DE LEITURA: 12 a 15 MIN
Melhorar seus processos de desenvolvimento de software por meio de revisões de código regulares é mais fácil de falar do que fazer.
Embora existam amplos méritos em boas revisões de código, uma solicitação de pull (PR) geralmente recebe apenas um olhar rápido e um polegar para cima - ou a frase mais tradicional, 'Parece bom para mim!'
Por isso, produzi aqui um guia completo com dicas e técnicas para a construção de um processo eficaz de Code Review para te ajudar a elevar a qualidade do seu código e, consequentemente, das entregas do seu time.
Esse processo é o que compartilho no Tech Lead Program do IFTL, onde me aprofundo citando cases das empresas onde trabalhei e disponibilizo frameworks para a escolha das metodologias mais adequadas para o contexto do negócio.
![](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/663e88826384b2308e32be67_banner-body-tech-hub-cto01%20(5).png)
O que é Code Review e por que é importante?
Antes de mergulharmos de cabeça no Code Review, vamos entender o básico.
O Code Review é um processo essencial no desenvolvimento de software, onde um ou mais colegas de equipe revisam o código-fonte escrito por outro desenvolvedor. Agora, você deve estar se perguntando por que isso é importante, certo? Bem, imagine que seu código seja um livro e o Code Review seja a revisão de um editor literário. Ele garante que o código seja claro, eficiente e livre de erros, o que é fundamental para manter um código de alta qualidade.
Antes da Revisão de Código
Antes de falarmos sobre os papéis de autor e revisor, precisamos falar sobre o que antecede a revisão de código para enfatizar práticas muitas vezes negligenciadas. Estas práticas, quando não devidamente valorizadas, podem impactar negativamente todo o processo de desenvolvimento. Chega o momento da revisão, e surgem dúvidas, atrasos, ciclos de revisão e entregas inadequadas, prejudicando o resultado do negócio.
4 práticas que você deve considerar antes do Code Review:
1. Arquitetura
Vamos iniciar esta discussão com uma pergunta que frequentemente surge em muitos times de desenvolvimento: uma tarefa que entra no desenvolvimento deve estar bem definida e compreendida por todos os membros da equipe, certo?
Suponhamos que a equipe já tenha dividido a história ou o épico e que esta seja uma tarefa menor que deve ser concluída em, no máximo, X dias, dependendo do time. Sugiro um prazo máximo de 2 dias, o que parece razoável, mas pode variar de acordo com o escopo, a equipe e outras considerações.
Dito isso, a arquitetura está definida, o que será feito está claro, seja uma tela ou uma API, e a equipe tem uma compreensão clara da definição de pronto para a história.
Sem essa clareza, torna-se difícil realizar uma revisão eficiente. Na minha opinião, a revisão de código não se limita apenas a identificar problemas de código, seguir padrões e verificar se há testes adequados. Vai muito além disso, contudo falaremos mais sobre isso quando abordarmos o papel do revisor.
O primeiro passo antes do processo de revisão de código é ter uma compreensão prévia do que deve ser feito, tanto do ponto de vista da arquitetura quanto da funcionalidade em si.
Claro, não estamos sugerindo que transformemos esse processo em uma abordagem "cascata ágil", mas devemos ser proativos para evitar cometer os mesmos erros e aprender com nossas entregas. Para exemplificar a importância e definir a arquitetura previamente, segue alguns aprendizados que tive:
Lições que aprendi com essa experiência
Nossa equipe precisava melhorar a importação de planilhas, que estava funcionando de forma ineficiente. Basicamente, estávamos fazendo streaming direto do arquivo para o servidor e, em seguida, processando-o linha por linha até ler todos os registros. Você pode imaginar o quão problemático esse serviço era e como afetava o desempenho geral da aplicação.
A equipe não era composta apenas por desenvolvedores experientes, houve algumas mudanças na estrutura e na atribuição dessa tarefa. Resumindo, não houve alinhamento mínimo em termos de arquitetura. A equipe que assumiu a tarefa presumiu que deveria fazer o upload direto do front-end para um storage (acertaram nesse aspecto) e adicionaram uma fila com o mesmo servidor como consumidor (cometeram um erro em relação à arquitetura esperada). Não me lembro de termos definido claramente a arquitetura, mas na minha mente estava claro o que era esperado.
Se tivéssemos uma descrição mínima da arquitetura esperada, alguns esboços e especificações, teríamos bloqueado essas mudanças na revisão inicial e acertado o desenvolvimento desta melhoria desde o início. Ter envolvido os membros mais experientes da equipe na revisão dessa tarefa específica também poderia ter garantido que a entrega atendesse às expectativas.
Quando temos uma compreensão clara da solução que iremos usar para resolver um determinado problema, tudo fica mais fácil. Isso inclui a descrição do que precisa ser testado, a preparação do ambiente de teste e homologação, bem como as decisões futuras ou tarefas a serem realizadas em conjunto. Nem tudo precisa ser automatizado desde o início, com 100% de cobertura de testes e segurança máxima. Ao ter essa clareza, podemos também identificar os débitos técnicos (linkar artigo débito técnico). Um projeto em que a equipe não tem conhecimento dos débitos técnicos está fadado a enfrentar problemas.
Portanto, é essencial incluir um passo para validar a arquitetura a ser implementada, seja durante o refinamento ou mais próximo da execução. Mantenha isso alinhado com a equipe.
Dicas de Leitura e Cursos para colocar isso em prática:
- "Upstream e Downstream no Kanban” e Big Design Up Front" por Raphael Batagini
- "Arquitetura Limpa" por Otávio Lemos
- "Clean Code e Clean Architecture" por Rodrigo Branas
- Assine a newsletter do Serverless Land
2. Trunk Based Development
O que diabos é isso, Sergião? Se o seu dia a dia se parece com a imagem abaixo, lamento informar que você está desperdiçando o tempo da sua equipe e o dinheiro do seu negócio. Segundo a documentação de DevOps do Google, baseada nas pesquisas da DORA Metrics, o desenvolvimento baseado em troncos é uma prática essencial para a implementação da integração contínua.
![Imagem de um diagrama de branches, mostrando um time que não utiliza o Desenvolvimento Baseado em Troncos.](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64ff3eb30a44c933e6e4129f_21ImB9c-JOaQshJmLuPGO6wz9BfpqFt7jXD5rI8wr8YKj2Q_WNdEo0rRwR3ojcNZKoB88brx-je4-L0X8sr6f-_DGYUxc4lKUzfsfUYjBy6qhoFJQLG5FGU73FEzqFlh4vhiMKvpHtkY.png)
O que exatamente o time que segue o diagrama acima está fazendo?
Ao iniciar uma nova funcionalidade, eles criam um branch específico para essa funcionalidade e trabalham nele até que a funcionalidade esteja totalmente pronta para ir para a produção. O que pode acontecer durante os dias, semanas e meses desse desenvolvimento? Se a equipe for um pouco mais esperta, fará a mesclagem com o branch principal de tempos em tempos. Caso contrário, em algum momento, algo semelhante ao meme abaixo pode ocorrer.
![Meme onde acontece uma confusão devido o git Merge](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64ff40918e5d3dfdb30b79ea_git-merge%20(1).gif)
Então, você quer que toda a equipe trabalhe diretamente no branch principal (main, master, ou qualquer que seja o nome usado na sua organização)? Isso!
É claro que, se a sua equipe for pequena e não houver um grande volume de alterações no branch principal, isso não será um problema imediato.
Mas essa é a abordagem que vocês precisam adotar: Fazer pequenas mudanças diretamente na produção. Isso pode ser um grande paradigma para muitas pessoas, e você provavelmente está pensando em vários cenários em que isso pode parecer incoerente, e você continua usando outros métodos para diferentes situações na sua empresa.
E qual é a relação disso com a revisão de código?
Quando lidamos com grandes mudanças de código, a revisão de código se torna falha, complexa, demorada e trabalhosa. Você precisará criar vários mecanismos e um processo de revisão de código extremamente burocrático para mitigar os problemas na entrega, mas isso não resolverá completamente, porque a revisão de código não pode ser 100% automatizada.
Existem vários passos a serem seguidos para atingir esse nível de maturidade de processo, e haverá resistência. Normalmente, usamos branches associados a ambientes, como mesclar com o branch main para ir para produção ou mesclar com o branch develop para ir para o ambiente de desenvolvimento, e assim por diante. Esse paradigma não ajuda na implementação do desenvolvimento baseado em troncos. O correto é que todas as solicitações de alteração, conhecidas como PRs, sejam direcionadas para um único branch, o main.
Hoje em dia, o Github Actions e muitos outros pipelines de automação de software oferecem acionamentos de diversas naturezas, e você pode gerar uma versão de qualquer branch. Há até mesmo a possibilidade de ter um pipeline automatizado de rollback e muitas outras funcionalidades que pretendo abordar em um artigo separado.
A conclusão deste tópico é que precisamos aprender a trabalhar com entregas pequenas para tornar o processo de revisão de código eficaz. O próximo tópico oferece insights para ajudá-lo a entregar software em produção diariamente.
Dicas de Leitura
- O tamanho do Pull Request é mais importante do que você pensa", por Victor Hugo.
- SourceLevel: Ferramenta de Métricas de Engenharia, criada por George Guimarães.
- Recursos técnicos de DevOps, por Equipe DORA.
3. Feature Flag
E mais uma vez: o que diabos é isso, Sergião? Você já deve ter implementado um sistema de controle de permissões, certo? Digamos que tenhamos dois tipos de perfis: um administrador, que vê todas as funções, e um usuário comum, que tem um menu mais enxuto no frontend e algumas validações adicionais no backend ao executar determinadas requisições, correto?
A Flag de Funcionalidade é basicamente isso: criar um código dinâmico que nos permite ativar ou desativar uma funcionalidade para um público ou contexto específico.
Martin Fowler, conhecido como o pai da refatoração, escreveu um artigo muito interessante em seu blog sobre "feature toggle" (que é a mesma coisa que "feature flag"). Lá, ele usou uma imagem interessante para mostrar os vários tipos de toggles em um software.
![Gráfico mostrando a relação entre a dinâmica e a longevidade dos tipos de toggles, retirado do artigo de Martin Fowler.](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64ff40a7e620fec0e7d68ad5_pyqcdztWhb_XBMXPIxQ6bhlsggs_ZkL_aIqkA8bVuc4CGCNx8mvyEjYtBRFXjfOdRGqVypV-ifusMbawU9kv74AuXPNInv_QGxAwafhqiTGHFWPy8L0ydYsa-FDfE4XrB3IeuBniDqD3.png)
Ele menciona um tipo específico de toggle que quero destacar aqui, chamado de "Release Toggles" (Toggles de Lançamento). Fowler afirma que esse tipo de toggle pode durar dias ou até semanas e geralmente só muda com uma nova implantação ou ao modificar alguma configuração em tempo de execução. Ele começa sua explicação com a seguinte introdução, que traduzi aqui para vocês:
"Essas são flags de funcionalidade usadas para permitir o desenvolvimento baseado em troncos para equipes que praticam a Entrega Contínua. Elas permitem que recursos em andamento sejam verificados em um branch de integração compartilhado (por exemplo, master ou trunk) enquanto ainda permitem que esse branch seja implantado na produção a qualquer momento. Os Toggles de Lançamento permitem que trechos de código incompletos e não testados sejam enviados para a produção como código latente, que pode nunca ser ativado."
O "papai" Fowler (o equivalente ao "papai" LeBron James, mas para programadores) resume exatamente o ponto ao qual quero chegar: as flags de funcionalidade são usadas para habilitar o desenvolvimento baseado em troncos, a fim de alcançar a entrega contínua.
Mas, Sergião, não entendi como aplicar isso na prática. Como fazemos?
Como aplicar a Feature Flag na prática?
Existem várias maneiras de usar isso, algumas das quais você pode já estar fazendo sem perceber.
Por exemplo, quando começamos a criar uma nova rota no frontend que só pode ser acessada por quem conhece a URL, isso pode ser uma saída para a sua equipe. No backend, é a mesma coisa: criar uma nova rota para testar e validar, e depois, ou lançar uma nova versão ou substituir a rota quando tudo estiver realmente homologado.
Para os desenvolvedores mais experientes, adicionar uma verificação de ambiente pode ser uma saída - aquele belo "if"!
![Demonstração do IF que fará algo só funcionar em desenvolvimento](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64ff40a7db0ab308cc09e836_SBe5p1Q6ysQCWwT7igZkRkrHaKCHO6DwcOH-xODKExjzFVohgis5vRtxK31cEygCnI8gsdOfMUG9k4HPpGBW8xH_jfntz_8ilVLypXHAPXtd-rUAtldgLCcuceVrDuOi5AH2yHWcb-rd.png)
Você também pode usar algo mais sofisticado, como o Redis na Upstash, ou o módulo de Experimentação da Optimizely, que é gratuito e usado pela Matchbox.
Percebeu como existem várias maneiras de colocar código em produção e no branch principal, sem afetar seu cliente final?
Claro que há cenários mais críticos a serem considerados, como infraestrutura e alterações em bancos de dados, mas a ideia principal é sempre pensar em como desbloquear sua equipe para que ela possa entregar software em produção.
Inclusive, no Tech Lead Program do IFTL, eu costumo analisar caso a caso dos alunos para indicar como vencer esse bloqueio na equipe de acordo com o contexto do negócio. Além desse tema, também abordo na aula sobre Metodologias para entrega de software com qualidade:
- Metodologias ágeis
- Code review
- Shape Up
- Como escolher uma metodologia
![](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/663e88826384b2308e32be67_banner-body-tech-hub-cto01%20(5).png)
4. Realização de testes
Compreendo que a cultura da revisão de código pode ser algo novo para muitas pessoas. Passei vários anos sem praticá-la, e inúmeros problemas surgiram no decorrer desse período, problemas que podem estar ocorrendo também no seu ambiente de trabalho devido à falta de conhecimento sobre essas práticas. Até mesmo porque há um tempo atrás, raramente se discutia sobre esse assunto.
Da mesma forma, por muito tempo, eu mesmo negligenciei os testes. Não estou aqui para criticar ninguém, mas, como líder da equipe da Matchbox nos últimos dois anos, enfrentei uma situação em que tínhamos pouquíssimos testes, quase nenhum. À medida que nossa base de código cresceu, conseguimos alcançar um nível aceitável de cobertura de testes em alguns projetos há apenas alguns meses. Convencer as pessoas da importância dos testes e de uma revisão de código sólida é uma tarefa árdua.
No entanto, essa mudança tem feito diferença em nosso cotidiano. Recentemente, Otávio Lemos compartilhou uma postagem impactante no LinkedIn:
![Citação do post de Otávio Lemos no LinkedIn sobre agilidade e testes] "Não há agilidade sem teste automatizado.](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64ff40a8d15ed6e7658d2466_0yRbJRARJihkir6r1W_uFUjVaUY9sUpTHpqi75YDTvcbM2CatNoAbV3UIhbeEwENl6-HeUaa0_EH9u32qBhhLHJ0rfXO7fqWzZqzzwPiiUvRWvMSK2jy629hUY_kyXdjth2rrKRTooTd.png)
Concordo plenamente com essa afirmação, pois, se desejamos impactar o negócio com entregas contínuas diariamente, como podemos garantir a qualidade das mudanças que estamos fazendo sem alguma forma de suporte?
Os testes estão diretamente relacionados à revisão de código, não apenas os testes automatizados, sejam eles unitários, de integração ou end-to-end. Estou me referindo também a testar o Pull Request (PR) de maneira efetiva: baixar o branch localmente, realizar as ações propostas pelo PR e avaliar os resultados reais. Falaremos mais sobre isso posteriormente, quando discutirmos o papel do revisor Tanto os testes automatizados quanto os testes manuais desempenham papéis fundamentais no sucesso das entregas.
É crucial compreender o quão crítica é a tarefa que você está desenvolvendo e reconhecer a importância de testes automatizados que garantam os resultados esperados. Por isso, incluí este item como uma etapa anterior à revisão. Deve ser um item obrigatório na lista de verificações do revisor e estar presente na mente de todos da equipe como um elemento fundamental para o sucesso das entregas.
Conclusão
Como você deve ter notado, busquei focar nesse primeiro artigo sobre Code Review em pontos que são primordiais para ajudar a diminuir o impacto das revisões e melhorar também a percepção do time de forma geral, tanto em velocidade quanto de resultado de negócio.
Ao estabelecer esse processo, você vai notar que conseguirá realizar experimentações mais rápidas, além de mudanças, porque processos burocráticos e as famosas subidas críticas irão diminuir ou acabar.
Continuem acompanhando o Tech Hub, no próximo artigo irei falar sobre o papel do autor no Code Review.
Esse é um tema que sempre enfatizo aos alunos do Tech Lead Program. Um líder de tecnologia só consegue crescer dentro da empresa, se conseguir delegar suas tarefas a outras pessoas, desenvolvendo as mesmas.
![](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/663e88826384b2308e32be67_banner-body-tech-hub-cto01%20(5).png)
Confira quais são os temas que abordo no Tech Lead Program do IFTL sobre Autogestão e Produtividade:
- Gestão de tempo
- Evitando microgerenciamento
- Autonomia com responsabilidade
![](https://cdn.prod.website-files.com/639c6acc2363a031e4058ba0/64fa3ebc939a4bf2574dbd22_1679931814721.jpeg)
Mentor
Sergio Fiorotti
Desde 2008 trabalhando com tecnologia nos maiores e-commerces do Brasil, empreendendo e ajudando startups. Formado em Sistemas da Informação pela FIAP em 2011, aprendendo, liderando e compartilhando conhecimento sobre liderança técnica desde 2016 pelo Brasil com mais de 1000 participantes e alunos em 2022. Atualmente sou Mentor IFTL e estou como sócio e Head de Engenharia na Matchbox Brasil, HR Tech focada em Employer Branding e Comunicação Interna com valor de mercado em torno de R$ 20 milhões.