Desenvolvimento

4 mai, 2015

Integração Contínua: mais atual do que nunca!

Publicidade

O assunto não é tão novo, mas mantém a sua importância: trabalhar com Integração Contínua causa um impacto positivo no processo de desenvolvimento, tornando o trabalho mais eficiente e diminuindo o número de retrabalhos.

Em equipes que adotaram as metodologias ágeis, com XP e Scrum, a CI (Continuous Integration, na sigla em inglês) é um dos pilares da agilidade. Com ela, é possível garantir que o sistema funcione a cada build de forma consistente, mesmo com equipes que trabalham remotamente e que estejam mexendo em diversas partes do código ao mesmo tempo.

Se a sua equipe ou empresa ainda não adotou uma metodologia ágil e a prática de Integração Contínua, é preciso um trabalho intenso para mudar a cultura e introduzir esses novos conceitos. É necessário utilizar os princípios e as boas práticas estabelecidas pela técnica, o que pode levar algum tempo e mostrar obstáculos pelo caminho. Porém, boas práticas, quando aplicadas por tempo suficiente, podem ajudar a mudar a cultura dentro de uma empresa e a aumentar as chances de que uma iniciativa de introduzir novos conceitos (como os de Integração Contínua) seja bem sucedida.

Os princípios básicos da Integração Contínua são:

  • Mantenha um repositório de versionamento de código
  • Automatize o build
  • Faça com que o build teste o código
  • Todos depositam mudanças no código todos os dias
  • Cada mudança entregue deveria passar pelo processo de build
  • Mantenha o processo de build rápido
  • Teste em um ambiente equivalente a produção
  • Torne fácil a obtenção dos entregáveis mais recentes
  • Qualquer um pode ver o resultado de um processo de build
  • Automatize a entrega

Esses princípios, como quaisquer outros, servem para orientar, nortear as iniciativas e ações de Integração Contínua na empresa, mas dificilmente deixam claro como exatamente agir para que sejam cumpridos. O papel de determinar como cada princípio ou grupo de princípios pode ser implementado é de um conjunto de práticas.

Dentro de um conjunto de práticas, há aquelas mais simples de executar, assim como as que estão mais ao alcance dentro do seu ambiente de trabalho, ou ainda as que tendem a dar os melhores resultados (em termos de efetividade e durabilidade). Essas são as práticas conhecidas como Boas Práticas, ou seja, comportamentos, atitudes e ações que podem ser usadas como modelos em diversas situações.

Neste artigo, vou apresentar diversas boas práticas relacionadas à Integração Contínua.

Princípio: mantenha um repositório de versionamento de código; todos depositam mudanças no código todos os dias, cada mudança entregue deveria passar pelo processo de build

Boa prática: mantenha sua estratégia de branching simples

Quando o assunto é controle de versão, sempre considere a possibilidade de usar, se já não usa, Git. Além de extremamente poderoso e fácil de usar, é o controle de versão do maior repositório de código aberto do mundo.

Existem muitas formas de organizar seu código no Git, mas manter uma estratégia simples é a melhor escolha para facilitar a automação e reduzir as chances de erro e confusão no repositório. Uma estratégia muito conhecida é chamada de GitFlow. Apesar de muito versátil, essa estratégia baseada em branches separados por ambiente/função exige um bom conhecimento de técnicas de merging e rebasing, e é recomendada para grupos com grande maturidade.

Mais simples e direto é utilizar um único branch (master) em todo o ciclo de desenvolvimento, exceto por efêmeros feature branches rapidamente reintegrados ao branch master. Essa técnica possui a vantagem de reforçar a integração a um único branch continuamente e o uso constante de tags para marcar certos momentos do código, como releases, hot fixes e a adição de novas features. É vantajosa também se você usa um servidor de Integração Contínua, como o Jenkins, pois facilita na padronização dos dados que seu pipeline recebe.

Princípios: automatize o build, automatize a entrega, torne fácil a obtenção dos entregáveis mais recentes

Boa prática: padronize seus entregáveis e a forma de levá-los até produção

Uma vez que seu código esteja entregue ao servidor de Integração Contínua, faça com que a saída dos dados após os testes e a aplicação de tags seja feita de maneira uniforme. Sejam pacotes WAR, RPM ou DEB, ou ainda imagens de máquinas virtuais (AMIs da AWS) ou de contêineres (usando Docker), garanta que todo o código possa sempre ser transformado em artefatos do mesmo tipo. Alguns artefatos são mais complexos que outros de serem gerados e mantidos e, em geral, começar por artefatos específicos de sistemas operacionais (RPM, DEB, MSI) é uma boa escolha.

Com o artefato de entrega definido, a próxima etapa é garantir que ele seja gerado uma única vez, e também seja promovido e instalado em todos os ambientes necessários sequencialmente até a produção. Essas etapas sequenciais de promoção e instalação devem ser idênticas ou muito parecidas entre ambientes, de forma que você não esteja testando apenas o software, mas o próprio processo de entrega.

Princípios: faça com que o build teste o código, mantenha o processo de build rápido, teste em um ambiente equivalente à produção

Boa prática: testes automatizados

É indiscutível que testar sua aplicação aumenta o nível da qualidade do produto final. Contudo, falar simplesmente em testar pode ser subjetivo demais, já que se todos os seus testes forem longos e repetitivos testes de regressão manuais que o analista de QA executa, ou se você tiver uma estratégia de testes incompatível com o ciclo de vida e as necessidades do seu produto, você ainda poderá dizer que sua aplicação possui testes.

O mais indicado é estabelecer uma estratégia de testes, ou seja, definir e discutir quais os tipos de testes expressam a melhor forma de manter alta a qualidade na entrega. Com uma estratégia bem definida, é muito importante que todos os (ou o máximo possível de) testes sejam automatizados. Isso pode significar rodar os testes de forma automática localmente, mas idealmente significa deixar o servidor de Integração Contínua realizar todos os testes automatizados toda vez que um código novo for adicionado ao repositório. Isso ajuda a manter a qualidade ao longo das diversas integrações de código.

O processo de executar testes automáticos deve ser rápido, levando apenas alguns minutos. Essa rapidez vai determinar o tempo que os desenvolvedores levam para saber se está tudo bem após a inclusão de novas linhas de código, e também vai definir quantas vezes é possível executar o conjunto de testes. Testes mais demorados e complexos podem ser executados fora do ciclo principal de build da aplicação, até mesmo em ambientes e horários pré-determinados. Entretanto, testes simples nunca devem ser tratados dessa maneira.

O ambiente em que você executa seus testes automatizados deve refletir muito bem o ambiente onde o código será executado posteriormente, em produção. Mas entenda que os ambientes não precisam ser idênticos (embora possam ser, idealmente). É necessário conhecer quais variáveis interferem no funcionamento da aplicação e fazer com que estas sejam o mais próximo possível dos servidores de produção. Um exemplo é que seu ambiente de testes deve possuir o mesmo sistema operacional (incluindo a versão) que seus servidores de produção. Para testes de integração entre diversas aplicações e suas dependências, também é importante que a arquitetura de infraestrutura escolhida para a produção seja a mesma dos ambientes de teste.

Princípios: qualquer um pode ver o resultado de um processo de build

Boa prática: métricas

A necessidade de possuir métricas a respeito do desenvolvimento e do ciclo de vida da aplicação é geralmente ignorada. E é exatamente o fato de ignorar métricas que faz com que as técnicas e os comportamentos associados à Integração Contínua muitas vezes pareçam trazer poucos resultados.

Como saber que o tempo do ciclo de desenvolvimento diminuiu se o lead time não é medido e exposto com frequência? Como saber que usando técnicas de Integração Contínua a qualidade do software entregue aumentou se não estamos acompanhando a quantidade de erros encontrados nas etapas automatizadas de testes ou erros encontrados em produção?

Possuir métricas de código (complexidade ciclomática, cobertura de testes unitários e integrados), temporais (tempo de execução de builds do servidor de Integração Contínua, lead time, cycle time), de entrega (quantidade de entregas realizadas com sucesso e com falha, quantidade de erros corrigidos e adicionados em produção após uma entrega) e de testes (número de bugs encontrados, número de bugs em correção e corrigidos) é imprescindível para quem pratica e, em especial, para quem ainda precisa convencer superiores e pares de que as práticas de Integração Contínua são importantes para melhorar a qualidade do código e do produto final.

Conclusão

Existem muitas técnicas diferentes que podem ser usadas para colocar em prática os princípios que listei aqui. Não há um único caminho, e nenhum caminho escolhido vai ser percorrido sem que seja necessário aplicar mudanças na forma como sua equipe ou sua empresa pensa, gerencia e entrega suas aplicações.

Comece pelas práticas mais fáceis de implantar para a sua realidade. Talvez seja subir a cobertura de testes do código, talvez seja colocar todas as aplicações pra serem entregues pelo servidor de Integração Contínua ou talvez seja espalhar pelo ambiente de trabalho monitores que mostram métricas para informar às pessoas que elas podem melhorar a qualidade e o processo de entrega.

Isso feito, tenha em mente duas coisas importantes: primeiro, a obtenção do comportamento e das práticas depende diretamente da cultura e do significado que esse processo tem para as pessoas. Ferramentas instaladas não vão resolver o problema se as pessoas não entenderem por que estão fazendo aquilo.

Segundo, não desista. Leia e informe-se sobre as técnicas que quiser aplicar e tenha paciência com quem ainda não entendeu e não tem o mesmo comportamento que você. Evite assumir a postura de “nós contra eles” e tente mostrar que todos estão no mesmo barco, independentemente se ele vai seguramente para o próximo porto, ou se vai direto para o centro da tempestade.

***

Texto publicado originalmente na Revista iMasters.