Automatizando seus Processos de Construção,
Compilação, Testes, Documentação e Implementação de seus Sistemas em .NET
Nesta primeira parte de nossa série sobre Integração Contínua – mais conhecida na comunidade como CI, o leitor aprenderá sobre o aspecto técnico e psicológico em implementar o conceito de Integração Continua e as vantagens e desvantagens de implementá-la nas organizações vencendo as objeções que aparecem durante o processo até a sua adoção em definitivo.
Nesta Série, nós também introduziremos o leitor com o uso muitas ferramentas gratuitas e de baixíssimo custo tais como Subversion, MSBuild, NAnt, Jenkins e CruiseControl.NET que são partes de um processo completo de Integração Contínua e demonstraremos em detalhes como usar estas ferramentas,neste artigo demonstraremos um processo de Integração Contínua simples. Vamos criar um pequeno Sistema de aprovação de execução de builds que nos dará um maior controle para que nossas alterações sejam publicadas em ambientes estáveis de desenvolvimento, Homologação e Produção. Criaremos um Estudo de Caso que será levado à efeito com o uso da Integração Contínua ao longo desta série. Contaremos o caso da Empresa de Software Fictícia Imbróglio de Códigos LTDA e como a mesma conseguiu se salvar da falência total implementando lentamente o que chamamos de Os 7 Ciclos do Sucesso para a Integração Contínua.
Como desenvolvedores, estamos interessados em desenvolver nossas
aplicações da melhor forma possível para os nossos clientes como um minimo de
esforço. Mas, nos tempos atuais, com aplicações mais complexas e tendo cada vez
mais "partes móveis", criar grandes aplicações está se tornando cada
vez mais difícil, mesmo com o avanço nas ferramentas de desenvolvimento, tais
como o Visual Studio e .NET Framework. Uma das chaves para a melhoria da
produtividade,e consequentemente das aplicações entregues, é a automatização da
parte repetitiva do trabalho e a
Integração Contínua é uma das melhores formas de se fazê-lo.
Não podemos crer que o Processo de Integração Contínua seja
a bala de prata ou a solução para todos os males, mas onde ela tem sido implementada,
tem tido grande sucesso e melhorias no processo de software para as equipes de
desenvolvimento.
A Integração Contínua, também conhecida como CI - Continuous
Integration - é o ponto central do desenvolvimento de software atualmente. De
fato, quando a CI é introduzida em uma empresa, torna-se o grande divisor de
águas, ela altera radicalmente a forma como as equipes pensam sobre todo o
processo de desenvolvimento. A CI tem o potencial de permitir e executar uma
série de melhorias contínuas e incrementais nos processos, indo de um processo
de simples agendamento de construção - vamos usar o termo build – até o processo de Entrega Contínua que culmina no processo
de publicação nos demais ambientes para Teste, Homologação ou Produção.
Uma boa infraestrutura que possibilite a Integração Contínua
pode simplificar o processo de desenvolvimento até a entrega do software ou de
sua iteração, auxiliando a identificação e correção de falhas rapidamente. Também facilita a
disponibilização de uma dashboard muito útil no Projeto tanto para
desenvolvedores quanto para outros profissionais da empresa que não são
desenvolvedores e, ultimamente, ajuda equipes a agregar mais valores ao negócio
e ao produto sendo desenvolvido para o cliente. Todo time de desenvolvimento,
não importando se grande ou pequeno, deve implementar e pensar como Integração Contínua.
O que é a Integração
Contínua?
Voltando aos dias dos Projetos desenvolvidos utilizando a
Metodologia em Cascata e controlando os cronogramas com gráficos de Gantt, bem
antes da introdução das práticas de Integração Contínua, o tempo e a energia da
equipe de desenvolvimento era drenada diretamente para um procedimento chamado
de Fase de Integração, que era executado sempre um passo anterior à entrega do
software. Durante esta Fase, a alteração do código era feita por alguns
desenvolvedores ou pequenos times que eram reunidos de forma isolada e se
juntavam apenas na integração de todo o trabalho já feito. Era um trabalho
complicado, na maioria das vezes durava meses, em uma integração com mudanças
de código conflitando entre si. Era muito dificil antecipar quais tipos de
problemas iriam ocorrer durante este processo e era ainda mais oneroso corrigir
os erros provenientes de tais integrações pois envolviam quase sempre retrabalho
e reengenharia de código criado meses ou semanas antes. Este processo
complicado, oneroso e doloroso, cheio de riscos e perigos, frequentemente
causava um grande atraso na entrega, custos não planejados e, como resultado de
tudo isso: clientes insatisfeitos. A Integração Contínua nasceu para resolver
estes problemas e sanar estas dificuldades. Na sua forma mais simples, a CI envolve
ferramentas que monitoram seus Sistema de Controle de Versão (Box 1) buscando
sempre alterações. Logo que uma alteração no código é identificada, O Servidor
automaticamente compila e testa o código de sua aplicação. Se algo dá errado, a
ferramenta imediatamente notifica os desenvolvedores para que eles possam
corrigir o problema imediatamente. Mas, a Integração Contínua pode fazer muito
mais do que isso.
Sistema de Controle de Versão (SCM).
É um
software que tem como principal funcionalidade, controlar versões de um
documento qualquer,ou seja, cada alteração que é feita neste documento, se
torna uma versão deste e o SCM controla de forma sequencial tais versões. Tal
software é muito utilizado em ambientes de desenvolvimento seja ele
corporativo ou não.
|
A Integração Contínua pode também ajudar a equipe a manter a
saúde do seu código, monitorar automaticamente a qualidade de código e as
métricas em seu código e desta forma auxiliar a manter a Dívida Técnica (Box 2)
controlada e os custos de manutenção baixos.
Dívida Técnica.
Dívida
Técnica descreve a dívida que a equipe de desenvolvimento assume quando
escolhe um design ou abordagem fácil de implementar no curto prazo mas com
grande impacto negativo no longo prazo.
|
A visibilidade pública das métricas de qualidade de código
encoraja os desenvolvedores a terem um maior cuidado quanto à qualidade de seu
código e melhorá-lo, devemos lembrar que o principal fundamento da Integração
Contínua não é punir, mas sim facilitar a manutenção do código afinal de contas
o código é de todos. Combinando testes de aceitação, a CI pode também funcionar
como uma ferramenta de comunicação, mostrando um verdadeiro Raio-X do estado
atual do Projeto em andamento dentro e fora da equipe. Pode simplificar e
acelerar a entrega auxiliando a automação do processo, deixando a publicação da
última versão da aplicação totalmente automática ou permitindo a operação com
apenas um aperto de botão. Em sua essência, a Integração Contínua age sempre na
redução de riscos à aplicação e seu desenvolvimento nos dando uma resposta
rápida.
Desta idéia, tiramos então uma conclusão lógica: precisamos
sempre enviar qualquer alteração de nosso código para teste antes de entrar em
produção. De certa forma, o uso da Entrega Contínua, está intrinsecamente
ligado a Integração Contínua, posto que esta termina e começa aquela que nada
mais é do que automatizar uma implementação do website, devolver um módulo
pronto ou outra atividade de fim pois a Integração Contínua é atividade de
meio. Então, uma abordagem pura da Integração Continua pode não ser apropriada
para todas as equipes. Um exemplo disto, é que muitos usuários não vêem com
bons olhos novas versões de software sendo entregues muitas vezes em uma semana
e com isto as solicitações para que os mesmos façam seus testes de aceitação e acabam
por preferir um ciclo mais espaçado e com um prazo no qual o mesmo possa efetuar
tais Testes.
O processo de Integração Continua, e em particular
Publicação Continua - Continuous Deploy - e Entrega Contínua - Continuous
Delivery, são muito mais do que entregar produtos para os usuários de forma
rápida. Quanto tempo seu time faz pequenas alterações de códigos antes de ir
para produção? Quanto custa o processo de resolver problemas que ocorreram há
muito tempo gerando grandes demandas de falha? Para que o CI possa resolver
todos os nossos problemas, devemos não só programar como Integração Contínua
como também devemos pensar como Integração Contínua.
Corrigir builds quebrados se torna prioridade absoluta e não
devem deixar estagnar o processo. O processo de implementação precisa ser
automatizado, com nenhum passo manual envolvido.
Uma das definições mais conhecidas de Integração Contínua
foi dita por Martin Fowler que diz: “Integração
Continua é uma prática dentro de desenvolvimento de software onde membros de um
time integram seu trabalho freqüentemente, normalmente cada um executa no
mínimo uma a várias integrações por dia. Cada integração é verificada por um
build automatizado (incluindo os testes) para identificar erros de integração o
mais rápido possível. Muitas equipes vêem nesta forma de trabalho uma redução
significativa nos problemas de integração e permitem uma equpe desenvolver
software de uma forma coesa mais rapidamente.”
Resumindo, um processo automatizado que constrói, testa, analisa
e implementa uma aplicação para ajudar e garantir que o processo funcione
corretamente seguindo as melhores práticas e as tornem entregáveis. Este
processo é executado em cada mudança de código fonte e permite resposta
imediata para a equipe de desenvolvimento. Diante disto, temos um termo que
precisamos compreender que é o Build.
O Build, nada mais é do que o processo de compilar, analisar e entregar o
assembly pronto para implementação. Exemplificando, pode ser que, desenvolvamos
uma camada da aplicação e commitemos seu código dentro do Controle de Versão,
logo, o Sistema de Integração Continua, quando for executar a sua tarefa
rotineira, irá compilar, testar e posteriormente gerar o assembly no local já
pronto.
Processos de
Desenvolvimento para Integração Contínua
Seu processo de desenvolvimento é ágil? Em sua equipe é
utilizada Extremme Programming - XP -, Scrum ou algum outro? Sua companhia é profundamente
enraizada em usar o método Cascata? Seu processo está em algum lugar entre Ágil
e Cascata? A resposta a estas perguntas não importa, porque todas as equipes
sem exceção devem seguir um processo parecido com o que é mostrado a seguir.
1. Baixa o código fonte, necessário
para a programação, de seu SCM.
2.
Faz alterações neste código.
3. No
Visual Studio, clica em Build e espera que o código compile com sucesso.
4. Volta ao passo dois, caso o Visual Studio
identifique erros.
5. Executa os testes unitários, e espera que tudo
fique verde, ou seja, que passe em todos.
6. Volta ao passo dois, caso o teste unitário
falhe, neste caso, o desenvolvedor vê um alerta vermelho e pode ver mais de um.
7. Refatora o código tornando-o mais
compreensível e então volta ao passo cinco.
8. Efetua o envio do seu código
alterado para o SCM, este trabalho é chamado de commit.
Vendo o processo demonstrado no parágrafo anterior e quando
começamos a utilizar o CI, notamos que seguimos o mesmo processo. Porém, para o
CI, o processo ainda vai mais além, posto que ele faça todos estes passos e
ainda continua após o commit do código por parte do desenvolvedor, como veremos
a continuação dos passos mais adiante.
9. O Servidor de CI observa as
alterações no SCM.Quando encontra qualquer nova alteração, ele efetua um
download da última versão do código contendo o último commit.
10. O Servidor de CI efetua o build do código.
11. O Servidor de CI executa o teste
unitário.
12. O Servidor de CI envia os resultados do builds
e o resultado dos testes para um sistema de comunicação, normalmente e-mail,
mas também pode ser em SMS, Mensageiro instantâneo ou outro, para informar aos
membros do time o estado do build.
Tipos de Construção
para a Integração Contínua
Os passos da Integração Contínua que descrevemos anteriormente
nos trazem o entendimento de que cada
vez que um desenvolvedor altera e sobe o código, um build é acionado, porém, em
verdade, este é o último objetivo e a razão pela qual este processo é chamado
de Integração Contínua.
Uma forma de começar a configurar o seu Servidor de CI é
obter as últimas alterações de seu código e efetuar o build.
No próximo passo, adicione os testes unitários. E então,
execute esta operação diariamente, que chamaremos de Build diário.
Mas, veremos que, em um determinado momento, um build diário
inclui outras coisas que não nos atendem quando fazemos um build incremental.
Quando temos builds executados todos os dias, podemos adicionar a este processo
mais dois ou três builds que apenas constroem e testam o software. Não demorará
e estaremos construindo e adicionando compilações diferentes para fazer coisas
diferentes o tempo todo. Existem tipos de builds que dependem do ambiente e da
natureza das aplicações, alguns dos builds mais comuns são mostrados na tabela
1.
Tipo de Build
|
Descrição
|
Contínuo
ou Incremental
|
É
executado quando o código é commitado no SCM. Executa uma compilação rápida e
um ou outro Teste Unitário.
|
Diário
ou Noturno (Daily ou Nightly Builds)
|
Executa
uma compilação e um gama maior de testes unitários e em alguns casos pode
executar testes adicionais como testes de aceitação e teste de Interface de
usuário.
|
Semanal
|
Executa
a compilação, testes de unidade completos e testes adicionais como testes de
aceitação, testes de fumaça e afins.
|
QA
|
Cria
um build apenas para verificações do pessoal do Setor de Qualidade contendo
as métricas para tal.
|
Staging
ou Pré-Produção
|
Consiste
em ser um servidor que age como uma réplica perfeita do ambiente de produção,
também pode ser chamado de pré-produção em alguns lugares. Nesta categoria, o
build é executado e retornando sucesso, deixa os assemblies disponíveis para
testes em pré-produção.
|
Release
|
Cria
um conjunto de instalação e então efetua os testes de instalação e todos os
outros processos necessários ao funcionamento do sistema em Produção e
retorna o feedback.
|
Tabela 1. Tipos de Build
O build mais importante, e é justamente o que nos dá o
resultado mais rápido, é o build contínuo ou incremental. Tal build é automaticamente
chamado quando o CI identifica uma alteração no código fonte commitado no SCM.
Como este build é executado muitas vezes durante o dia e um build pode ser
executado logo após o término de outro. Este pode ser executado a cada cinco ou
dez minutos.
Ocupando o segundo lugar em frequência, por ser executado em
um período mais espaçado, é o build diário, também chamado de build noturno.
Tal antítese pode ter gerado alguma confusão, posto que a pergunta que se faz
é: ele é noturno ou diário? A resposta é: não importa, posto que ele seja
executado uma vez por dia e preferencialmente quando não se tem quase nenhuma
atividade na infra-estrutura, pode ser um horário durante o dia em que todos
devem ter ido almoçar ou durante a madrugada, por isso a dualidade, que pode
ser conflitante em alguns casos, de conceitos. Tal tipo de build é agendado para
que execute todo um gama de testes unitários em todo o código, sem exceção, por
isso que é muito importante ter um seu Projeto uma estratégia de testes para os
módulos bem definida para que estes builds nos devolvam a informação verossímil
e necessária, também verificamos a qualidade do software utilizando Cobertura
de Códigos e Métricas de software.
Outro tipo de build é o Build Semanal, que executa
automaticamente e de forma usual sempre aos finais de semana. Uma vez por
semana é o suficientes para medirmos a qualidade de nosso código e executar Testes
adicionais com ferramentas para testes de fumaça como Selenium, FitNesse e NUnitForms. Também, podemos criar a documentação
de nosso código utilizando SandCastle e fazer a Integração Contínua de nossa
base de dados.
Para um controle maior da data de liberação das novas
versões do seu sistema, além do build semanal, também seria recomendado um
build de release.
O propósito do build do release é criar um conjunto de
instalação e executá-lo. Este build normalmente é executado manualmente. Mas,
após o build ser iniciado, todos os outros passos são executados
automaticamente. No build de release, o CI compila todo o código Fonte, executa
todos os testes criados, incrementa o número de versão e etc. Então é criado o
conjunto de artefatos para a implementação do mesmo e posterior teste desta
implementação. Podem existir outros tipos de builds de acordo com as
necessidades.
CI em alguns passos
para a sua organização
A Integração Contínua não é a solução para todos os nossos
problemas como já foi dito anteriormente. Claro que introduzir a CI dentro da
empresa nos mostra um caminho a percorrer através de ciclos distintos. Cada um
destes ciclos envolve melhorias que são incrementais entre si para todo o corpo
técnico, sejam eles servidores ou profissionais da equipe de desenvolvimento
bem como melhorias na cultura e estrutura de trabalho. Vamos mostrar nos
parágrafos seguintes, um pouco de cada ciclo organizado do mais elementar ao
mais maduro em uma empresa fictícia, a Imbróglios no Código LTDA, que estava à
beira da falência, mas que acabou se organizando e utilizou a CI como o ponto inicial
de sua alavancagem e crescimento Financeiro, dos 10 Analistas Iniciais dentro
do Estado do Rio de Janeiro, a Imbróglios hoje em dia emprega mais de 3.000
profissionais de TI nos cinco continentes, muitos dos Analistas da época
tornaram-se gestores. A Imbróglios no Código estava à beira da falênca, mas não
por erros apenas de seus profissionais de desenvolvimento, mas por não disporem
de uma infraestrutura competitiva. Enfim, a empresa havia parado no tempo e
começou a ouvir as opiniões de seus colaboradores, em reuniões diárias, como
último recurso para evitar a completa bancarrota, nestas reuniões a palavra Integração Contínua e
outros termos sobre o mesmo assunto foram mencionadas e também os gestores identificaram
que membros da equipe já detinham tal conhecimento oriundo de experiências
anteriores, mas que no passado a gerência não os permitia implementar tais
idéias porque "não havia espaço no cronograma e o tempo era curto".
Apesar de uma parte da equipe declarar oposição diante desta medida, que
veremos como tal resistência foi combalida, a Diretoria comprou a idéia e deu
um prazo de 5 meses a contar daquele momento e transcrevemos abaixo os trechos
mais importantes da consultoria na qual este autor tomou parte e participou do
processo para que o leitor acompanhe ciclo por ciclo como a Integração Contínua
pode mudar a filosofia de trabalho de uma organização.
Primeiro Ciclo. Não existe Servidor
de Build. Inicialmente, a equipe ainda não dispõe de nenhum tipo de Servidor
Central de builds. O Software é compilado e construído manualmente na máquina
do desenvolvedor, mesmo que se use um Script NAnt ou similar. O Código Fonte
dos Projetos é armazenado em servidores centralizados, mas desenvolvedores nem
sempre commitam suas alterações neste Servidor. Antes que uma versão estável
ser liberada, um desenvolvedor executa a integração, das alterações no código
fonte da aplicação, de forma manual, este processo gera um grande prejuízo no
que tange a ultima parte: integração manual de código.
Segundo Ciclo. Builds Noturnos ou
Diários (Nightly ou Daily). O time agora dispõe de um servidor para builds
e builds automatizados são agendados em um período regular, sendo tipicamente à
noite ou durante o dia quando o fluxo de trabalho é interrompido por algum
período - horario de almoço coletivo, reunião diária entre equipes ou afins,
algo que cause queda de utilização do link. Estes builds apenas compilam os
códigos, ainda não existem Testes Unitários sendo executados. Testes Unitários
quando existem, não são parte integral ou obrigatória do processo de build. Desenvolvedores
commitam suas alterações de Código Fonte regularmente, normalmente, no final do
dia. Se um membro da equipe de desenvolvimento efetua um commit de seus códigos
e este conflita com o trabalho de outro membro da equipe, o servidor de builds
alerta toda a equipe via e-mail na manhã seguinte. Porém, faz-se mister que o
time ainda utilize o servidor de builds com o único propósito de informar as
quebras e nada mais, logo a equipe acaba se sentindo desobrigada à corrigir toda
a compilação interrompida para corrigir apenas aquele build em sua estação de
trabalho, e o build pode ficar quebrado no servidor de por um tempo maior.
Terceiro Ciclo. Builds Noturnos e
Automação de Testes Básicos. O time agora já está começando a tirar
proveito da Integração Contínua com Testes automatizados mais seriamente. O
servidor de build está configurado para dar início a um novo build assim que um
novo código é commitado para o SCM e aos membros do time é permitida a livre
visualização da alteração do código gerou a execução do Build e qual o impacto
desta mudança. Além disso, o script que executa o build compila a aplicação e
executa um conjunto de testes unitários ou testes de integração automatizados.
Com relação ao envio de mensagens à equipe, o servidor de builds também envia
um alerta aos membros do time sobre problemas na integração utilizando não só o
e-mail, mas como outras formas mais proativas como mensageiros instantâneos.
Builds que ficam quebrados agora são corrigidos mais rapidamente.
Quarto Ciclo. Tem início a
Revolução das Métricas. Agora a equipe dispõe de verificação da Qualidade
de Código automatizada e validação de métricas quanto à cobertura do código
junto às melhores práticas, auxiliam muito na verificação para a eficiência dos
nossos testes. Existe um build que incide apenas sobre a verificação da
qualidade do código, ou seja, em um processo que é executado de forma distinta
dos outros builds mostrados anteriormente, este ocorre sempre, de forma
separada, sobre a versão mais estável que está sendo executada, também gera uma
documentação sobre a API utilizada para a criação da aplicação, facilitando
assim a organização do código e escalabilidade da infraestrutura da aplicação ao
longo do tempo o que facilita a chegada de novos membros à equipe e diminui o
tempo de treinamento do novo recurso. Este tipo de implementação da CI ajuda a
equipe a manter a qualidade do código sempre em alto nível, informando ao time
quais métricas/práticas de testes estão sendo eficientes e úteis ao processo. O
time também dispõe de um Painel de Acompanhamento de Builds, que consiste em
mostrar os resultados de todo o Projeto em um Monitor na Sala ou no corredor da
empresa de forma que todos tenham visibilidade de todos os processos de CI que
estejam sendo executados e os status destes.
Quinto Ciclo. Testando de forma
mais aprofundada e automatizada. Os benefícios da Integração Congtínua são
intimamente relacionados à práticas de testes bem consolidadas dentro da
equipe. Agora, práticas como Desenvolvimento Orientado a Testes, TDD, são
largamente utilizados resultando em um crescimento na confiança dos resultados
dos builds automatizados. A aplicação não é mais simplesmente compilada e
testada, mas se o teste tem sucesso, este é automaticamente implementado para
um servidor de aplicação para testes de outros tipos tais como testes de
Aceitação e Testes de Desempenho e chegando a este ponto, já podemos começar o
6º e penúltimo ciclo, o dos Testes de Aceitação e Implementação que levará a
empresa à filosofia da Entrega Contínua.
Sexto Ciclo. Testes automatizados
de Aceitação e uma implementação melhor elaborada. O Desenvolvimento Orientado
à Testes de Aceitação é praticado, guiando esforços de desenvolvimento e
providenciando sempre relatórios de alto nível do estado atual do Projeto.
Estes testes automatizados utilizam ferramentas para Desenvolvimento Orientado a
Comportamentos, BDD, que agem como agentes para comunicação e documentação
assim como as ferramentas de testes que publicam relatórios sobre os resultados
de testes nos termos de negócio que profissionais que não sejam de
desenvolvimento possam entender. Uma vez que testes de alto nível sejam
automatizados dentro do projeto o mais cedo possível no processo de
desenvolvimento, eles também dão a idéia de que melhorias foram implementadas e
o quanto falta para a entrega da iteração ou do Projeto como um todo. A
aplicação é automaticamente implementada no ambiente especifico para testes
junto ao pessoal da Qualidade, ou QA, tão logo as alterações sejam commitada no
SCM ou em uma base de build noturno. Uma versão estável do software projetado
poder ser implementada em ambiente controlado, como pré-produção por exemplo,
utilizando um build executado manualmente, caso a Equipe de Testes julgar
estável. A equipe de desenvolvimento também será capaz de utilizar o servidor
de build para proteger a versão estável gerando um rollback para uma versão
anterior, se algum erro brusco e crítico ocorrer.
Sétimo Ciclo. Entrega Contínua.
Existe um confiança colocada nos testes automatizados de Unidade, de Integração
e de Aceitação de tal forma que as equipes podem aplicar as técnicas de
implementação automatizada no Ciclo 6, porém, caso tudo corra bem, podem
permitir que o CI implemente-as diretamente em produção em caso positivo dos
builds. É este tipo de procedimento que configura a Entrega Continua e pelo que
pudemos ver no decorrer deste processo,a única intervenção humana neste
processo foi executada no ciclo 6 para testes de implementação.
Será dentro destes ciclos que nossa série de artigo irá
funcionar, utilizaremos estes 7 ciclos de forma a mostrar de forma prática para
o leitor como que o CI vai evoluindo dentro da Organização e como o nosso
script de build vai sendo incrementado durante a implementação das melhorias.
Porém, diante de toda esta revolução como foi visto anteriormente, grandes
objeções surgem por estarmos lidando com o fator humano que não é feito à
mudanças. Podemos vencer os mais resistentes com simples respostas para
complexas perguntas e será o que veremos à seguir.
Lidando com a
resistência às mudanças
Com todos estes builds acontecendo e membros da equipe tendo
que modificar a sua rotina e efetuar atualizações em seus códigos, com os
códigos mais atuais para se manterem atualizados motivados por um servidor de
SCM, de forma freqüente, ou seja, quase que diariamente, podemos encontrar
certas objeções dos membros do time e as mais comuns veremos a seguir.
CI aumenta a manutenção. Algum membro terá de manter o
Sistema de CI. Tal procedimento fará com que este membro saia de seu escopo de
ser apenas um desenvolvedor. No início, existirá um tempo maior que gerará um
excesso de trabalho ao membro da equipe, porém, o time terá uma grande economia
de tempo posto que o grande gargalo conhecido, que era o da Integração manual,
não irá ocorrer e tornará o teste da aplicação mais simples. Muitas equipes
informam, e isso é facilmente encontrado na Grande Rede, que após o processo de
CI ser implantado, as rotinas de manutenção demoram menos que uma hora por
semana na média.
Estas mudanças são rápidas demais e são muitas. É difícil se adaptar a uma
nova forma de se fazer algo. Não implementar tudo de uma só vez. Começar com um
build simples executado uma vez ao dia e então adicionar um teste unitário.
Após o time se sentir mais confortável e se acostumar com esta rotina podem
adicionar um ou mais builds por dia ou começar a executar uma Análise de
Código. Por implementar o processo em pequenos passos e mostrar que estes
pequenos passos nos retornam grandes resultados - principalmente em tempo e
facilidade, teremos mais aceitação dentro deste novo processo.
CI implica em uma custo adicional de hardware e de software. Comece com um PC antigo como
seu servidor de CI se conseguir. Eventualmente, vamos precisar melhorar o
hardware para que possamos executar builds de forma mais veloz (devemos nos
lembrar de que um build de integração, demora no mínimo, 5 minutos), mas para
builds executados de duas à três vezes ao dia, máquinas antigas também vão nos
atender. Se as ferramentas que informarmos nesta série forem utilizadas como
recomendamos, o seu custo com software será mínimo.
Desenvolvedores devem compilar e testar. Não estamos tirando estas
responsabilidades dos desenvolvedores. Estamos apenas movendo boa parte do
trabalho mais demorado e oneroso para um Sistema automatizado. Tal medida fará
com que os membros da equipe possam produzir mais e resolver melhor os
problemas de Regras de Negócios que existam na aplicação, logo esta medida fará
com que os desenvolvedores fiquem mais produtivos aonde importa: Escrever e
identificar erros no código.
O Projeto é longo demais ou está adiantado demais para que
adicionemos o CI.
Embora seja muito melhor e mais fácil se colocar um projeto na CI desde o seu
início, a verdade é que, muito do trabalho que é feito é justamente dentro de
manutenção dos nossos Projetos já existentes. Um projeto que já exista pode não
ter Testes Unitários, mas podemos utilizar um SCM e precisar fazer builds
destes. Podemos nos beneficiar da CI não importando o tempo e o tamanho do
Projeto.
Se a CI for colocada em seu devido lugar, muitos dos
problemas mais conhecidos dentro de um Projeto de Software: do desenvolvimento
à entrega e manutenção devem ocorrer. Mais adiante, vemos muitas razões para
que se utilize o CI em seu processo de desenvolvimento.
Riscos Reduzidos. Implementando bons processos
de CI, criaremos software com uma performance muito melhor que a habitual
porque já teremos feito os testes unitários e testes de integração de código
muito mais cedo dentro do processo, então aumentamos as chances de corrigir
erros também muito cedo. Falaremos sobre Riscos na próxima e derradeira seção
desta primeira parte.
Produto
implementado de forma simples.
Se automatizarmos o processo de instalação. Nós saberemos sobre o comportamento
de sua instalação antes de receber um feedback de problemas do cliente.
Visibilidade de
Projeto. O
mecanismo de feedback permite aos membros da equipe saber sobre os resultados
do build e onde estão os problemas. Os problemas podem ser corrigido o quanto
antes e esta abordagem reduz custos e o tempo gasto corrigindo problemas.
Não permita que as objeções dos membros nos obrigue a recuar
ou resistir. A resistência inicial irá diminuir gradualmente quando a equipe
começar a trabalhar diretamente com o Sistema de CI. Uma Terapeuta Familiar
muito conhecido em outros países chamada Virginia Satir criou o Modelo de
Mudanças Satir que se refere sobre como as famílias lidam com a mudança. E
transportando algumas diretrizes para lidar com a equipe, temos a seguir algumas
boas recomendações. E este processo de mudança envolve cinco passos.
Passo 1. Status Quo Tardio. Todos estão trabalhando normalmente no
processo atual e todos sabem como ele funciona.
Passo 2. Resistência. Um novo elemento é introduzido no seio da equipe.
As pessoas são sempre hesitantes para mudar a sua rotina. Se o status quo
funciona muito bem, por que modificá-lo?
Passo 3. Caos. O novo elemento introduzido é adotado. Não há uma
forma normal de fazer novas coisas. Rotinas diárias são despedaçadas.
Passo 4. Integração. Pessoas se ajustam lentamente ao novo modo de
se fazer coisas. Fica mais fácil fazer o trabalho de convencimento se utilizar
esta abordagem. E começam a utilizá-lo, mas de forma gradual.
Passo 5. Novo status quo. O novo elemento já está totalmente
integrado ao Sistema. As pessoas agora o vêem como Normal e voltamos ao passo
1.
Quase todos os times acabam adotando novas metodologias de
uma hora para outra. Este processo por soar familiar. Assim como lutamos contra
a resistência da equipe, sejamos persistentes em implementar as mudanças. Os
membros do time em breve vão aceitá-las. Alguns membros vão adotar o CI mais
rápido que outros alguns podem precisar de uma dose maior de convencimento.
Talvez seja necessário mostrar a eles como o CI reduz os riscos e os custos e
benefícios dentro do processo de desenvolvimento.
Custo Benefício da
Integração Contínua
Seu cliente não gosta de riscos. Seu gerente não gosta de
riscos. Seu Gerente de Projetos precisa ter planos para mitigar os riscos. No
fim, não vamos gostar de riscos. CI é sempre apontado como uma redução nos
riscos. Talvez o maior risco dentro do desenvolvimento de software é o não
cumprimento de prazos, em outras palavras o projeto sendo entregue mais tarde
do que o acordado e contratado. Por causa do mecanismo de feedback no processo
de CI, os membros do time sempre vão saber do estado do build atual, que nos
auxilia a saber se o projeto está dentro dos prazos.
Veremos o mecanismo de feedback mais adiante em nossa série
de artigos.
O outro grande risco é o risco de defeito, os chamados bugs.
Como já mostramos anteriormente, que quanto mais tardia é a política de
defeitos aplicada a um projeto, maior será o custo para corrigi-los. Algumas
estimativas sugerem que o custo para a correção de um defeito gira em torno de
R$3.500,00 em média para corrigir um simples defeito de software em aplicações
internas. Anos atrás, uma companhia de antivírus bem conhecida gerou defeito
dentro de um de seus pacotes de atualização. Este pequeno defeito fez com que
os clientes perdessem confiança naquele antivirus e forçaram a empresa a
reduzir seus rendimentos trimestrais e previsões orçamentárias de receita em
US$8.000.000,00. Não gostaríamos de ver a nossa empresa passar por algo
parecido.
Uma das vantagens da CI neste ponto é que os defeitos são
corrigidos tão logo eles são identificados. Integrando e testando o software a
cada build, podemos identificar e corrigir defeitos no processo. Discutiremos
Testes Unitários mais adiante em nossa série de Artigos.
Sempre fizemos algumas perguntas para saber o andamento de
nosso projeto como: consideramos quantos caminhos diferentes podem existir em
nosso código fonte? testamos a combinação de cada if/else? Quantos casos de
declarações switch foram testadas? respondemos estas perguntas implementando a
Cobertura de Código.
Cobertura de Código é a metodologia que verifica quais
caminhos serão testados e quais não serão. Uma grande solução quando o assunto
é cobertura de código é que podemos automatizá-la em nosso processo de CI. É
humanamente impossível de serem testadas todas as combinações de cobertura
existentes, mas quanto mais for testado, menos problemas serão descobertos pelo
seu cliente.
Outro risco conhecido são as atualizações em Bancos de
Dados. Nunca foi fácil adicionar campos para uma tabela ou novas tabelas em um
Banco de Dados.
Com Integração Contínua em Banco de Dados, teremos ciência
se as mudanças implementadas trabalham corretamente e sem perda de dados.
Demonstraremos Integração Contínua em Bancos de Dados mais adiante nesta série.
Desenvolvedores odeiam padrões de codificação e
arquiteturais, mas têm seu propósito útil: permitem que a aplicação siga as
melhores práticas, fazem com que a aplicação funcione melhor e fica mais fácil
de manter. Revisões de Código identificam muitos problemas; mas, como Revisão
de Código é um processo manual, algumas coisas podem se perder. Então, por que
não automatizar a verificação da padronização em seu processo de CI? cobriremos
também a Revisão de Código mais adiante nesta série.
Comentários são colocados raramente no código e a
documentação quase não existe. Muitos dizem que se formos ágeis, não precisamos
de documentação, mas isso não é verdade. O Manifesto Ágil diz que o trabalho é
mais valorizado que a documentação. Mas, a documentação é ainda necessária,
especialmente se estivermos criando assemblies a serem utilizados por outras
equipes ou outras pessoas em forma de APIs. Esta é outra oportunidade para
automatizar seu processo com processos de CI. Cobriremos esta parte também
nesta série de artigos mais adiante.
Como saberemos que o processo de instalação/implementação
funcionou corretamente? Existem poucas coisas que frustram mais usuários do que
não conseguirem instalar ou implementar uma aplicação. É fácil ver problemas
escondidos no Projeto que sem um sistema de CI só seria identificado muito
depois do processo de desenvolvimento, quando os problemas já se tornaram bem
mais difíceis e caros para se corrigir. Agora que já sabemos o que a Integração
Continua é e como ela pode melhorar nossos processo de desenvolvimento nas
próximas partes veremos o processo de CI ser implementado gradualmente seguindo
os ciclos informados nesta primeira parte.
Nesta primeira etapa de nossa série sobre a Integração
Contínua, vimos os grandes problemas que são encontrados em projetos,
organizações e equipes de forma que preparamos o leitor para os desafios que
serão encontrados nesta busca pela excelência em seus projetos e tal excelência
começa com o Sistema de Integração Contínua. O maior obstáculo para a
implementação não está no Projeto em si, mas na resistência das equipes em
implementá-lo dentro das organizações.
Assim que a resistência é combalida demonstrando no dia a
dia como a CI é útil e viável, a implementação começa a mudar de forma lenta,
mas drástica a forma como as organizações interagem dentro do Projeto de
Software. Tendo mais agilidade, as equipes conseguem melhores resultados.