Entregas eficientes: mantendo o desempenho através de testes de unidade
Quando pensei em escrever sobre testes, me pareceu bobeira, pois já existem inúmeros materiais sobre o tema na internet atualmente. Mas deu muita vontade de falar sobre isso após ver uma projeção a qual mostrava que a cada cinco anos, o número de desenvolvedores no mundo dobraria.
Isso significa que a cada cinco anos, aproximadamente cinquenta porcento dos desenvolvedores no mundo terão menos de um ano de experiência no mercado! E esse ciclo parece não parar tão cedo…
Com isso em mente, me senti na responsabilidade de bater nessa tecla, já apagadinha, mais uma vez… nem que seja para fazer um refresh sobre o assunto, pois é uma forma de reforçar a ideia de que ele sempre será relevante.
Contextualizando
Se você já teve a oportunidade de participar de um projeto totalmente do zero, no início da sua carreira como desenvolvedor, deve se lembrar como você foi super produtivo, escrevendo código como uma máquina, não é mesmo? Pois bem… vou contar a história do programador novato chamado Joãozinho, para contextualizar aqueles que não tiveram tal oportunidade.
A história de Joãozinho
Joãozinho era recém formado e conseguiu seu primeiro trabalho como desenvolvedor. Ele foi contratado para trabalhar em um projeto novo, totalmente do zero. Joãozinho estava muito empolgado e ansioso para fazer a diferença na empresa!
Após se inteirar sobre o negócio e entender um pouco mais sobre o projeto, ele e seus companheiros de equipe (também novatos) receberam as primeiras features, e finalmente, começaram a fazer o que mais gostavam: codificar!
A produtividade estava a mil por hora! Joãozinho e sua equipe estavam fazendo as entregas de maneira muito rápida!
O product owner falava:
- Precisamos de uma nova feature para daqui dois dias, é possível?
Ao que Joãozinho respondia prontamente:
- Claro, perfeitamente possível!
Um dia depois, a feature já estava pronta até mesmo antes do prazo! E isso se repetiu para diversas novas features consecutivas! O product owner estava maravilhado com a eficiência do time, em particular com a de Joãozinho. Era algo realmente incrível!
Até que em um certo dia sombrio, alguns meses depois do início do projeto, a produtividade estranhamente começou a diminuir…
Novas implementações que antes levariam dois dias para ficarem prontas, passaram a demorar uma ou duas semanas… O PO começou a questionar a equipe sobre o motivo de tal mudança.
Joãozinho se prontificou em responder:
- O projeto está ficando complexo. Uma mudança no ponto A pode impactar no ponto B, e consequentemente em N pontos! Precisamos deste tempo grande para garantir que tudo vai funcionar corretamente.
Um ano desde esses acontecimentos se passou… Joãozinho hoje, após errar várias vezes as estimativas para as novas features do projeto em questão, e ficar mal perante o gerente por fazer falsas promessas, passou a dar uma resposta única sempre que era questionado sobre prazo, e a reposta era:
- Vai levar uns três meses.
Em uma tentativa desesperada para contornar o problema, a empresa resolveu contratar mais engenheiros… O problema de novas pessoas em projetos é que eles sugam toda a energia dos desenvolvedores mais experientes, e eventualmente, eles acabarão no mesmo ponto, ou seja, também pedirão aproximadamente três meses para implementar uma nova feature.
Essa pequena história de terror do Joãozinho, é um erro clássico, o qual é gerado principalmente por causa de uma coisa: pressa. Quando agimos com pressa, a chance de fazermos besteira aumenta consideravelmente.
Evitando o erro do Joãozinho
Como o próprio Uncle Bob costuma dizer: “The only way to go fast is to go well”, ou, em tradução livre: “A única forma de fazer algo rápido, é fazendo direito.”
Joãozinho, pela sua falta de experiência, negligenciou diversas questões importantes que garantiriam que o nível de produtividade fosse mantido. Uma dessas questões que foi esquecida, e que possui um papel importantíssimo, foi a cobertura de testes.
Sem testes, perdemos o controle sobre o código e ele passa a nos controlar. Isso é um completo absurdo… Nós deveríamos ser o mestre do código, ele quem deveria nos servir, e não o contrário.
Quando perdemos o controle sobre o código, passamos a temê-lo. Temendo o código, deixamos de fazer coisas importantes, como a refatoração. E em falta da refatoração, não conseguimos fazer o que nós, humanos, sempre fizemos por anos: aprimoramento.
“Sem testes, perdemos o controle sobre o código e ele passa a nos controlar.”
E esse medo do código é real. Voltando para a história do Joãozinho, durante o desenvolvimento do projeto, teve situações em que ele olhou para o código e pensou: Vou melhorar isso aqui!
Porém, logo depois, um outro pensamento tomou conta de sua cabeça: Nossa, mas se eu mudar qualquer coisa aqui é perigoso…
Percebe como o código está limitando as ações do Joãozinho? Agora, imagine se ele dispusesse de um artifício, um botão por exemplo, que quando pressionado, indicasse através da emissão de luzes nas cores verde ou vermelha, se a modificação que Joãozinho acabou de fazer deu certo ou não.
Joãozinho fez uma modificação que não teve impacto negativo? Emite luz na cor verde. Fez algo que quebrou o sistema em algum ponto? Emite luz na cor vermelha.
Com um mecanismo desse tipo, Joãozinho perderia o medo de realizar melhorias no código e passaria a ter controle dele. Agora, pasmem, esse artifício existe! Mas não é um botão, e sim, os testes de unidade.
Testes de unidade
Quando falamos de testes, em termos de produtividade no curto prazo, eles também nos trarão alguns benefícios, como por exemplo, nos poupar tempo evitando aqueles processos tediosos de debug pela IDE para descobrir pontos de falha.
Além disso também facilitarão nosso entendimento sobre o domínio, pois geralmente são bem autoexplicativos. Mas o principal benefício ainda continua sendo o de longo prazo.
Uma coisa é fato, depois que se começa a criar testes é difícil parar, porque torna-se algo realmente divertido, principalmente se utilizarmos um flow de desenvolvimento orientado por testes como o TDD (Test-Driven Development).
Mas algo do tipo não dá para ser aplicado da noite para o dia. É impossível acordar em uma bela manhã de sol e falar que vai aplicar TDD sem nunca o ter utilizado.
Aliás, eu não recomendo ninguém tentar aprender TDD no trabalho. Isso além de não ser nada interessante em termos de desempenho, muito provavelmente irá frustrar o desenvolvedor, que se verá perto da deadline de alguma entrega, e não terá nem código de produção e nem teste para apresentar como resultado.
Esse tipo de disciplina, como qualquer outra, exige prática deliberada. Nesse sentido, eu aconselho quem quer tornar esse tipo de prática divertida para ser incorporada no dia a dia, procurar adquiri-la fora do horário de trabalho, para que só depois que se sentir confortável e confiante, passar a utilizá-la no dia a dia.
Eu mesmo estou fazendo várias dessas práticas para entender melhor as armadilhas que podem aparecer usando esse approach antes de tentar qualquer coisa nos projetos em que trabalho.
Existem vários exercícios de TDD que você pode encontrar por aí, onde você pode explorar seu uso. Vou deixar aqui alguns desses exercícios para quem tiver interesse:
Mas depois de falarmos sobre esses detalhes de teste de unidade e sua importância, fica a questão: um desenvolvedor que não cria testes para seu código, está sendo menos profissional?
Profissão: desenvolvedor
Se pararmos para pensar, a palavra profissão, vem de “professio,onis”, que tem o sentido de professar, declarar, prometer, jurar…
Porém, diferente de algumas outras profissões, nós não prometemos ou juramos nada formalmente, ou seja, não temos um código ético (com o perdão do trocadilho) que devemos seguir de maneira rígida para não sermos punidos pela justiça caso não o façamos, é quase como se não tivéssemos uma “profissão” analisando pela origem da palavra.
Isso deixa as coisas meio “soltas” em nossa área. Não chega a ser um velho oeste, mas em alguns casos extremos realmente vira uma terra sem lei.
Por isso, se realmente queremos nos considerar profissionais no sentido original da palavra, podemos professar/jurar que faremos certas coisas a respeito do nosso próprio trabalho, afim de garantirmos um certo padrão de qualidade, regras que não vamos deixar de seguir em hipótese alguma, e dentro dessas regras podemos incluir como um dos itens na lista a criação dos testes de unidade, por exemplo.
Concluíndo
Como vimos até aqui, pressa definitivamente não é a resposta, e ignorar a questão dos testes pode ser um erro grave em um projeto.
Ao fazermos uma entrega apenas com o propósito de fazer uma feature rodar, estamos resolvendo o problema de maneira eficaz, porém, precisamos ser eficientes se quisermos manter o nível de desempenho.
Bom, por hoje é isso. Tentei levar esse texto mais para o lado filosófico do que para o técnico. Me dê um feedback sobre o que está achando deste formato. Você pode me alcançar pelas redes sociais que estão no meu perfil, ou comentando aqui embaixo.
Forte abraço, e até a próxima!