Shift Left é uma prática em desenvolvimento de Software onde tentamos encontrar defeitos o mais cedo possível no processo. (Esquerda -> Origem, Direita -> Destino)

Segundo pesquisas o custo de encontrar e corrigir defeitos aumenta exponencialmente quanto mais longe ele é encontrado no ciclo de desenvolvimento.

Imagem retirada do PDF linkado acima.

É indiscutível que o cenário ideal é encontrar os defeitos já na fase de design, evitando assim desperdício de tempo reescrevendo código. Mas aqui eu quero focar na fase de implementação, quando o desenvolvedor está com a mão na massa.

No final de 2019 entrei numa vaga DevOps e grande parte do meu trabalho tem sido voltado à qualidade de código na nossa unidade de negócios. Para referência a nossa unidade desenvolve primariamente código para sistemas embutidos, FPGAs, automação industrial e similares. Alguns dos produtos que desenvolvemos são altamente regulamentados pois são controladores de robôs industriais que podem acidentalmente matar alguém devido a um bug no código.

Como pode-se imaginar o custo de desenvolver código dessa qualidade é imenso. Sem contar que cada ciclo de release é extremamente longo. Passar por desenvolvimento, testes, integração, homologação e implementação sempre foi bem penoso, manual e entediante.

Em 2018 a empresa resolveu abraçar DevOps e é para resolver os problemas acima que meu time está trabalhando.

Testes Unitários

O passo mais importante – e que precisa ser constantemente relembrado – é que escrever testes unitários não é uma coisa a ser feita depois. Nem por outro time. Testes devem ser escritos pelo desenvolvedor concomitantemente com o código. Na minha opinião é a parte mais importante de Shift Left. Você não espera a próxima fase, testes, para saber se tem algum defeito óbvio no código.

Não entenda errado, ter uma fase de testes ainda é importante, mas o grosso dos testes deve ser feito na fase de implementação através de testes unitários que devem ser executados constantemente. Isso também ajuda a diminuir a carga de trabalho do time de testes e permite que se importem com coisas mais importantes do que testar o básico.

Revisão de código

O próximo passo considero revisão de código. Ninguém deveria fazer merge de código diretamente no trunk, certo?

Mas o principal aqui é que o desenvolvedor vai criar um branch, escrever o código ali (testes inclusive) e ao invés de fazer merge no trunk diretamente ele manda o código para revisão. Um ou mais desenvolvedores devem olhar o código e verificar se está OK. Eu recomendo seguir as práticas do Google.

Uma grande quantidade de defeitos pode ser encontrada aqui, mais uma vez resolvendo os mesmos mais à esquerda.

Pre-commit

Um dos lados negativos de revisão de código é que seres humanos não gostam de ter seu trabalho criticado. Vir outro desenvolvedor e dizer que alguma coisa está obviamente errada é duro de ouvir. Não vou ter a referência à mão, mas li um artigo que indicava que desenvolvedores estão mais inclinados a aceitar correções sugeridas automaticamente por ferramentas do que por outros seres humanos. E é aqui que sugiro utilizar pre-commit hooks.

Utilizando o pre-commit você já pode pre-programar um bocado de testes para serem rodados no código que você está a ponto de fazer commit. Alguns dos meus favoritos são: linters (includindo yaml e json), ferramentas que verificam se tem algum segredo vazando (Chaves AWS, SSH, certificados privados), ferramentas de estilo, etc.

O pre-commit não deixa você nem fazer push do código se ele não passar no controle de qualidade ali mesmo, na máquina do desenvolvedor. Garante que pelo menos o básico estará coberto antes do código ir para revisão.

Editor de texto e plugins

E por último, o que eu considero o mais à esquerda possível, é o editor de texto / IDE que o desenvolvedor está utilizando. É aqui que eu gosto de pegar todos os meus problemas e fazer o máximo para melhorar o código.

Eu sou usuário e fã do Microsoft Visual Studio Code. Não só o editor por si mesmo é sensacional, mas existe uma pletora de plugins – pagos e gratuitos – que são extremamente úteis.

Minha linguagem é Python e o VS Code tem suporte extensivo para a mesma, com language server maduro e útil. Eu também tenho integrado linter e até o black.

Uso também plugins que utilizam IA, como o Sourcery e o TabNine. Esses plugins sugerem código conforme estou escrevendo ou sugerem refatorizar trechos imediatamente quando termino de escreve-los.

Se você utiliza Sonarqube também tem um plugin chamado Sonarlint que analisa seu código e mostra os problemas assim que você aperta CRTL + S.

Conclusão

Nenhuma dessas coisas que citei acima é a panaceia. Leia Code Complete do Steve McConnell se quiser mais detalhes em quanto cada um desses passos ajuda a reduzir defeitos.

Porém o efeito acumulativo de todas essas ferramentas juntas, além de uma mentalidade focada em qualidade, com certeza diminui muito a quantidade de defeitos antes mesmo de chegar na fase de testes. Isso ajuda a diminuir o custo e o tempo total de entrega do projeto.