Minha palestra no Agile Trends Brasil 2015

agiletrends-03
364

Hoje palestrei no Agile Trends Brasil, na trilha de DevOps, para lembrar as pessoas que Nem só de startups vive o mundo: Build-Measure-Learn em sistemas corporativos.

Há quem diga que “DevOps é a segunda década do Agile”. Concorde você com isso ou não, o fato é que muitas empresas estão procurando em DevOps a solução para todos os seus problemas – como já fizeram no passado com outras palavras da moda.

Continue lendo “Minha palestra no Agile Trends Brasil 2015”

Porque você definitivamente precisa de testes de unidade

(AVISO: Este post é uma tradução livre do excelente post originalmente publicado por Colin Dembovski, também MVP de Visual Studio ALM, em http://www.colinsalmcorner.com/2013/07/why-you-absolutely-need-to-unit-test.html. Thanks, Colin!)


Porque você definitivamente precisa de testes de unidade

Eu escrevi sobre porque builds são absolutamente essenciais no desenvolvimento moderno de aplicações (parte 1) e por que o Team Build é um grande mecanismo de build (parte 2). No entanto, se você não inclui testes de unidade em suas builds, é como escovasse os dentes sem creme dental – há muito movimento, mas não é a maneira mais eficaz de se fazer as coisas. Neste post, quero propor algumas reflexões sobre por que você definitivamente precisa usar testes de unidade.

Aqui vão alguns destaques:

  1. Codificar com testes de unidade em mente obriga-o a pensar sobre o design e a arquitetura de seu código – o que faz com que ele se torne um código melhor
  2. Testes de unidade fornecem feedback imediato – todas as alterações no código são testadas (pelo menos em parte) à medida que você codifica.
  3. Um pequeno investimento agora leva a uma enorme economia mais tarde – bugs em produção custam muito mais do que bugs em desenvolvimento
  4. Testes de unidade fornecem métricas para a qualidade do seu código
  5. Testes de unidade trazem qualidade inerente às suas implantações (releases)

Vamos analisar cada um desses pontos.

Desenvolvimento guiado pelo pensar

Você provavelmente já ouviu falar de termos como “test-driven development (TDD)” (desenvolvimento guiado por testes) ou “behavior-driven development (BDD)” (desenvolvimento guiado por comportamento). Adoraria cunhar mais um termo – desenvolvimento guiado pelo pensar. Eu venho de um histórico de desenvolvimento – e como eu amo codificação (como a maioria dos desenvolvedores), sofro da síndrome de “deixe-os-detalhes-para-lá-quero-apenas-começar-a-codar”. A maioria dos desenvolvedores que conheço também. Espero que você nunca perca esta paixão – mas há muito a ser dito para tomarmos fôlego e pensarmos primeiro.

Se você apenas pular no código e não tiver testes, você provavelmente vai criar algo que funcionará de imediato para algumas situações (geralmente com a ressalva do “funciona na minha máquina!?!”). No entanto, isso não é sustentável já que leva ao que um  professor universitário meu costumava chamar de “código espaguete” (o que foi especialmente engraçado já que ele é italiano). Você escreve algum código e o implanta. Algo quebra. Você faz um remendo e reimplanta. Agora você quebrou alguma outra coisa. Então você põe um pouco de fita adesiva (metaforicamente, é claro). Eventualmente você chega ao ponto do chiclete e da folha de alumínio, e as coisas vão de mal a pior.

Se você começa a escrever testes (ou pelo menos começa a escrever seu código com testes em mente), é mais provável que você escreva um código melhor. Se você alguma vez tentou escrever testes de unidade para código legado, vai entender o que quero dizer. Se você não codificar com testes em mente, seu código (como seria de se esperar) acaba não-testável (ou pelo menos muito difícil de testar com testes de unidade). Escrever código testável o obriga a pensar em boa decomposição, boas interfaces, boa separação de preocupações (SoC, separation of concerns), inversão de controle (IoC, inversion of control) e injeção de dependências (DI, dependency injection) e um montão de outros princípios que todos nós aprendemos, mas de alguma forma esquecemos de usar em nossa rotina diária.

Então comece com seus testes. Isto o obriga a usar todas as coisas boas (não são chamadas de boas práticas por acaso). O pouco de pensamento necessário no início vai te poupar muita dor ao longo do tempo (para não falar da diminuição da quantidade de chiclete que você vai encontrar no seu repositório de fontes).

Feedback imediato

Deixe-me fazer uma pergunta – quão longo é o ciclo de feedback entre o momento em que você escreve algum código e quando você obtém feedback sobre a validade desse código? Ou formulado de outra maneira, pense sobre o último bug que você consertou. Qual é a duração do tempo entre a escrita do código e o relatório do bug? Um dia? Uma semana? Um ano?

O fato é que quanto mais cedo depois de escrever o código que você encontrar um bug, mais barato será para conserta-lo. Vamos considerar duas extremidades do espectro: tempo de codificação e em produção.

Quando existe um bug em produção, pode levar algum tempo para encontra-lo. Em seguida, é relatado para o suporte técnico. Eles investigam. Eles então escalam para o suporte de segundo nível. Eles investigam. Eles então escalam para os desenvolvedores, que tem que investigar e reproduzir. Em outras palavras, um longo tempo.

E quando você está codificando? Você escreve algum código e executa os testes de unidade. O teste falha. Você investiga e corrige. Em outras palavras, muito pouco tempo.

Quanto mais rápido você receber feedback (e quanto mais vezes você obtiver feedback), mais eficiente e eficaz você será. Numa larga escala, essa é em geral a razão para metodologias Ágeis – a iteração rápida aumenta a frequência do ciclo de feedback. Isso funciona no nível de gerenciamento de projeto, e também funciona no nível de codificação.

Eis com o que isso se parece em um gráfico:

clip_image001
350

Quanto mais cedo você encontrar seus bugs, tão menos tempo que você vai gastar encontrando-os e mais barato será para corrigi-los. Se você não tem testes de unidade, você já vai mudar sua primeira oportunidade de feedback para a terceira zona (teste manual). Se você não fizer o teste manual, você está empurrando de novo ainda mais para fora em direção aos testes de aceitação do usuário (UAT, user acceptance test). Se você não fizer isso, então o primeiro feedback que você vai conseguir é da produção – que é o mais demorado e o mais caro.

Obter feedback imediato enquanto você está codificando é ótimo quando você está fazendo projetos “greenfield” (projetos que nunca foram implantados antes). Ele realmente começa a brilhar quando você volta depois de 6 meses (ou 12 ou 18) para adicionar recursos – você ainda tem sua suíte de testes para garantir que você não está quebrando nada com o seu novo código.

Gastar um pouco agora – economizar muito lá na frente

Quase nunca falha: os times que não têm testes de unidade alegam que “não têm tempo para teste de unidade”. Defendo que na grande maioria dos casos, é exatamente porque não se investe em testes de unidade que você não tem tempo para codificar corretamente. Sempre que você implanta código não-testado, você aumenta sua dívida técnica. O fato triste é que a dívida técnica tende a crescer exponencialmente.

Olhe novamente para o gráfico acima. Onde você acha que você vai gastar mais tempo para encontrar e corrigir bugs? Obviamente, quanto mais “à direita” você está, mais tempo você precisa para corrigir um bug. Então invista um pouco “agora” enquanto você está codificando, de modo que você não tem que gastar muito tempo mais tarde lidando com problemas em produção!

Métricas de qualidade

Como se mede a qualidade do seu código? Erros na produção por período de tempo? Tempo médio de reparo (MTTR, Mean Time To Resolve)? A maioria dessas medições é útil em algum grau, mas como são estatísticas de “tempo de produção”, o feedback vem muito tarde no ciclo.

Os time com que trabalho que tem métricas invariavelmente têm métricas de teste de unidade – taxas pass/fail e estatísticas de cobertura de código. Os times que não têm métricas quase sempre não têm testes unitários. Testes unitários fornecem uma medida objetiva da qualidade do seu código. Como você pode melhorar se você não sabe onde você está atualmente?

Qual cobertura que você deve estar almejando? Isto é discutível, mas eu sempre recomendo que você prefira se concentrar em suas tendências – certifique-se que cada implantação é melhor que a última. Dessa forma, o número absoluto realmente não importa. Mas a única maneira que você pode fazer qualquer tipo de análise de tendências é se você realmente está coletando as métricas. É por isso que adoro testes de unidade (com cobertura de código) no TFS Team Build, uma vez que as métricas são agrupadas dentro do data warehouse e é realmente fácil de fazer relatórios de tendências. Mostrar à área de negócios um gráfico com uma constante melhoria da qualidade é uma das melhores coisas que você pode fazer como um desenvolvedor!

Qualidade inerente

Todas estas práticas levam à qualidade inerente – uma qualidade que faz parte intrínseca do que você está fazendo do dia-a-dia, ao invés de algo que você coloca no final de uma iteração (ou rapidamente antes do lançamento). Se você incluir qualidade inerente em seus processos e práticas, você pode dormir tranquilamente na noite da grande implantação. Se não o fizer, você vai ter que manter o telefone por perto para todas aquelas chamadas inevitáveis de “Socorro, o sistema está quebrado…”

Código legado

Na minha empresa anterior, tivemos grandes quantidades de código “legado” – que estava em produção, que nós mantínhamos constantemente, e que não tinham testes. Quando comecei a direcionar para testes de unidade e cobertura, inevitavelmente chegamos ao momento embaraçoso onde alguém deixou escapar, “Mas tem muito código para começar a testar agora!”. Argumentei que 1 teste era melhor do que 0 testes. E 2 testes são melhores que 1 teste e assim por diante.

Então criamos uma política em que qualquer código em que você trabalhou (sejam novos recursos ou correções) precisava ter testes de unidade. Isto nos colocou no caminho para a construção de nossa suíte de testes abrangentes. Também definimos uma política de que a cobertura de código tinha que ser maior nessa implantação do que na implantação anterior para que a entrada em produção fosse aprovada. No começo, nossa cobertura foi 1,5 ou 2%. Depois de apenas 6 meses, estávamos perto dos 40% de cobertura. E o número de problemas de produção em que estávamos trabalhando diminuiu dramaticamente.

Conclusão

Assim como você não pode deixar de fazer builds automatizadas, você realmente não pode se dar ao luxo de não fazer testes de unidade. O investimento agora proporcionará benefícios enormes ao longo do ciclo de vida do seu aplicativo – não só para você e seu time, mas também para o seu negócio e as partes interessadas também.

Para ler mais, Martin Hinshelwood escreveu um ótimo post sobre o test-first que eu recomendo.

Feliz Testes!

O que é o treinamento Professional Scrum Developer para mim

imageNesta semana de 04 a 08 de março estou em Chicago fazendo algo que chamam de PSD TTT (Professional Scrum Developer Train The Trainer). É um curso restrito da Scrum.org para formar e selecionar potenciais novos instrutores para o curso de Professional Scrum Developer.

Hoje, depois de voltar do terceiro dia de curso, peguei-me refletindo sobre toda a bagagem de informação que recebi nestes três primeiros dias – e, em especial, sobre o que me trouxe até aqui.

Provavelmente a maioria dos leitores deste blog não deve ter a menor ideia disto, mas já ministro treinamentos há quase 20 anos. Aliás, é bem engraçado lembrar que meus primeiros treinamentos de ferramentas de desenvolvimento foram os cursos de dBASE e Clipper na SOS Computadores em 1994… Smile

O fato é que, apesar de ministrar treinamento há tanto tempo, nunca fui formalmente um instrutor/professor “profissional”. Minha profissão, no sentido estrito da palavra, sempre foi a de programador (que já virou analista programador, desenvolvedor, engenheiro de software… nem sei mais do que chamamos hoje em dia Open-mouthed smile). Lecionar, para mim, sempre foi muito mais uma paixão –  um hobby remunerado  – do que um trabalho, visto que nunca foi minha atividade principal.

Assim, o melhor dos mundos para mim sempre foi juntar minhas duas paixões – desenvolver sistemas e  lecionar – em uma só: treinar pessoas a se tornarem (melhores) desenvolvedores. Certamente foi essa a motivação que me levou a começar a estudar ALM (que, em 2005, ainda chamávamos de SDLC) e TFS. A ideia de compartilhar experiências com as pessoas ao meu redor, dividindo o pouco que eu sei e aprendendo ainda mais no processo de ensinar sempre me fascinou.

Entretanto, quando me tornei efetivamente um consultor de ALM, ajudando times e empresas a melhorar seu ferramental de suporte ao processo de desenvolvimento, ficou óbvio que havia uma peça ausente no quebra-cabeças. Não fazia o menor sentido melhorar o ferramental à disposição do time se eles não sabiam como usa-lo. E não fazia o menor sentido ensiná-los a usar o ferramental se eles não fossem capazes de transcender a ferramenta para chegar ao que realmente interessa: entregar software de qualidade (no sentido mais amplo da palavra qualidade).

Durante todo meu tempo como programador sempre tive o infortúnio de atuar em times disfuncionais. Não quero, com isso, desmerecer as pessoas com quem trabalhei – pelo contrário! Trabalhei com alguns caras realmente brilhantes. Mas talentos individuais não fazem, necessariamente, um bom time. E mesmo um bom time, por sua vez, não consegue ir muito longe se a cultura que o cerca não faz nada além de sufocá-lo.

Foi na busca por alternativas que me deparei com as Práticas Ágeis (ou aquilo que chamamos simplisticamente de Agile). Foi óbvio que essa era a peça que estava faltando. De nada adiantavam os processos e as ferramentas de ALM (que são úteis, claro!) se não dermos a devida atenção às pessoas e as interações entre elas.

Depois dessa epifania, que pode soar até idiota agora mas que estava longe de ser óbvia, ficou claro que de nada adiantaria ajudar meus clientes a adotar o ferramental de ALM sem trazer junto as práticas de engenharia de software do XP (Extreme Programming) e as práticas de gestão de projetos do Scrum para acabar com os (aparentemente insolúveis) problemas de desenvolvimento de projetos/produtos complexos. Ou seja, o “mundo perfeito” seria um time capaz de utilizar as melhores práticas de engenharia de software, amparadas por valores fundamentais como Transparência, Inspeção e Adaptação (tendo por trás o devido suporte do ferramental que diminui o trabalho braçal e garante a consistência e previsibilidade do resultado) para entregar valor de maneira contínua a seus clientes.

Como resolver isso, então? Como colocar um time no caminho correto, vendo seus projetos de maneira mais ampla e não apenas focando num pedaço da solução?

A resposta à essa pergunta para mim, hoje, é:

“O curso Professional Scrum Developer é o primeiro, e com isso talvez o mais importante, passo na direção correta.”

Extraído do site da Scrum.org, o curso de Professional Scrum Developer é:

The Professional Scrum Developer course teaches students how to work in a team, using modern software engineering practices and your specific technology platform to develop an increment of potentially releasable functionality. All of this is done as iterative incremental development within the Scrum framework.

O curso Professional Developer Scrum ensina os alunos a trabalhar em equipe, usando práticas modernas de engenharia de software e sua plataforma de tecnologia específica para desenvolver um incremento de funcionalidade potencialmente entregável. Tudo isso é feito como desenvolvimento iterativo incremental dentro do framework Scrum.

Note que a proposta do curso é mostrar tudo de maneira integrada, exatamente como deveria acontecer na vida real: as práticas de engenharia (como TDD, CI, Refatoração, ATDD…) suportadas pelo ferramental (que no caso do PSD.NET é o Visual Studio e o TFS) e guiados pelo Scrum.

Estar aqui em Chicago, participando deste TTT, é uma oportunidade única para mim de poder também ministrar esse treinamento no Brasil (hoje só o Giovanni Bassi o tem ministrado).

Dividir um pouco das minhas experiências, poder aprender ainda mais com as experiências dos alunos – e ainda por cima poder ajudar essas pessoas a melhorar seu dia-a-dia em suas empresas para entregar mais software de qualidade e principalmente melhorar sua qualidade de vida. Não vejo a hora!!!

Um abraço,
Igor