Esse artigo faz parte da revista Java Magazine edição 35. Clique aqui para ler todos os artigos desta edição

Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. 

Integração Contínua no XP

Usando o Eclipse e o CVS para implementar mais uma prática do Extreme Programming

Descubra o que projetos XP fazem para possibilitar que diversos desenvolvedores trabalhem juntos em um mesmo projeto, integrando suas contribuições de forma harmônica e segura

Em uma equipe com vários desenvolvedores, todos trabalhando na elaboração de um mesmo sistema, qual a melhor forma de unificar as diversas alterações feitas na base de código? Processos ágeis como o Extreme Programming utilizam a prática conhecida como Integração Contínua para solucionar essa questão.

A integração contínua consiste em integrar o trabalho diversas vezes ao dia, assegurando que a base de código permaneça consistente ao final de cada integração. Nesse artigo, você conhecerá os passos necessários para usar essa prática em seu dia-a-dia, primeiro de forma manual, com foco nos conceitos, e depois de forma automatizada.

Repositórios e versionamento

Uma das ações mais importantes para permitir que diversos desenvolvedores trabalhem juntos em um mesmo projeto é utilizar um sistema de controle de versões, que chamaremos aqui de "repositório de código" ou simplesmente "repositório". Existem muitos desses sistemas disponíveis no mercado, tais como CVS, Visual SourceSafe, Subversion, ClearCase, entre outros. Nesse artigo iremos utilizar o CVS para apoiar nosso exemplo. Trata-se de um software open source amplamente utilizado em todo o mundo.

Repositórios de código fornecem um local centralizado para armazenamento dos arquivos de um projeto, e também controlam as versões desses arquivos. Imagine, por exemplo, que num projeto haja uma classe CestaCompras com capacidade apenas de listar e calcular o valor total dos produtos na cesta, e que um dia alguém implemente também a inserção e a remoção de produtos. Ao armazenar o código atualizado com as novas funcionalidades, o repositório grava uma nova versão da cesta. Ou seja, a classe CestaCompras original não é simplesmente substituída por uma nova. Ao invés disso, o novo código é anexado ao antigo.

Guardar versões é como ter um botão de "desfazer" à nossa disposição. Quando cometemos um erro em um arquivo e o colocamos acidentalmente no repositório, o repositório nos permite recuperar a versão anterior. No caso da classe CestaCompras, por exemplo, imagine que a primeira versão funcionasse perfeitamente e, ao implementarmos a inserção e remoção de produtos, tivéssemos inserido um bug por falta de atenção. Suponha ainda que o bug só fosse percebido quando a classe já estivesse em produção. Nesse tipo de situação, a possibilidade de controlar versões com um repositório de código é muito útil, por exemplo, porque nos permite obter a versão original rapidamente (a que funcionava) e colocá-la no ar até que a versão mais recente (com problemas) seja corrigida.

Quando diversas pessoas trabalham juntas em um projeto, o repositório se torna o destino final de tudo o que é produzido. Quando um desenvolvedor armazena seu trabalho no repositório, dizemos que está fazendo uma integração, isto é, está integrando o que acabou de produzir com o que seus colegas também vêm produzindo e armazenando no repositório.

Formas de integração

Em um projeto, com várias pessoas trabalhando juntas, é comum acontecerem situações nas quais dois ou mais desenvolvedores precisem editar determinado arquivo ao mesmo tempo. Como tratar essa possibilidade?

Existem duas abordagens utilizadas. Na mais simples, o primeiro desenvolvedor que precisa editar um arquivo faz um checkout desse arquivo e, enquanto o estiver editando ninguém mais consegue alterá-lo. Ou seja, o arquivo passa a ter apenas acesso de leitura para todos os outros desenvolvedores. (Fazer um checkout significa trazer uma cópia de um ou mais arquivos do repositório para a estação de trabalho do desenvolvedor.) É possível usar esse modelo de edição de arquivos em repositórios como o Visual SourceSafe, por exemplo.

A outra abordagem, que iremos tratar com mais detalhes ao longo do artigo, é adotada frequentemente por usuários do CVS e de outros repositórios. Nela, cada desenvolvedor faz checkout de todo o projeto para a sua máquina, e tem liberdade para editar qualquer arquivo sem ter que se preocupar se outras pessoas também estarão editando o mesmo arquivo que ele.

Quando termina sua tarefa, o desenvolvedor pede ao CVS para integrar seu código ao repositório. Para cada arquivo que alterou, o CVS verifica se outra pessoa também fez alterações. Quando isso ocorre, torna-se necessário fazer um merge, isto é, unificar as alterações dos diferentes desenvolvedores. 

O merge pode ser automático ou manual. O merge automático ocorre quando o CVS detecta que duas pessoas editaram o mesmo arquivo, porém constata que linhas diferentes foram alteradas. Nesse caso, o CVS simplesmente aceita as duas (ou mais) alterações no arquivo. Já quando dois programadores editam a mesma linha de código, torna-se necessário fazer um merge manual. Então, o CVS marca no código o trecho em que existe o conflito e o programador tem que analisar manualmente as mudanças e decidir como os códigos devem ser unificados.

O modelo de trabalho do CVS traz uma série de vantagens, mas parece mais arriscado que aquele em que desenvolvedores editam arquivos exclusivamente. Entretanto, utilizando as recomendações que veremos adiante, você poderá utilizá-lo de forma segura. Assim poderá editar arquivos livremente, sabendo que na hora de integrar não irá causar nenhum mal aos arquivos já presentes no repositório.

Integração através de um exemplo

Para que você possa experimentar o processo de integração, iremos ajudá-lo a simular o que aconteceria em um pequeno projeto, cujo objetivo é criar uma calculadora usando práticas do Extreme Programming. Sendo assim, além da Integração Contínua, outras práticas previamente abordadas em artigos na Java Magazine também serão usadas, tais como Programação em Par (apresentada na Edição 33) e o Test-Driven Development (Edição 32), mas não é necessário conhecer detalhes sobre essas técnicas para acompanhar o artigo.

Nesse exemplo, iremos considerar uma equipe composta por quatro desenvolvedores: Ana, Bruno, Carlos, e Denise. Eles irão trabalhar em pares, e usarão dois computadores diferentes. Em um computador, Ana e Bruno irão trabalhar juntos, enquanto no outro estarão Carlos e Denise. O Eclipse será utilizado no projeto. 

Para simular as condições exatas desse projeto, será necessário criar em seu computador dois workspaces, um para cada par. No meu computador, por exemplo, criei os seguintes diretórios:

 

/Users/vinicius/workspaceAB (para o par Ana e Bruno)

/Users/vinicius/workspaceCD (para o par Carlos e Denise)

 

Você também deverá ser capaz de abrir duas cópias diferentes do Eclipse, de modo que possa alterar o conteúdo de cada workspace, à medida que avançarmos na explicação. Uma forma simples de fazer isso é instalar o Eclipse em dois diretórios diferentes. No meu caso, por exemplo, ele foi instalado nos seguintes diretórios:

 

/Users/vinicius/eclipseAB

/Users/vinicius/eclipseCD 

 

Finalmente, você precisará ter acesso a um servidor CVS. Se estiver em um ambiente administrado, onde já exista um CVS instalado, peça acesso ao responsável pela infra-estrutura. Caso contrário, você poderá baixar e instalar o CVS a partir dos links fornecidos ao final do artigo. Explicar como instalar o CVS está fora do escopo desse artigo, mas os links e livros sugeridos serão úteis nesse sentido.

Iniciando o exemplo

Iremos começar simulando o par Ana e Bruno. Para isso, execute o Eclipse reservado para eles. Em seguida, configure-o para utilizar o workspace destinado a esse par, através da opção File|Switch Workspace. Veja a Figura 1.

Criando o projeto e os diretórios

Crie um novo projeto Java chamado "Calculadora" e configure os diretórios onde serão armazenados os códigos fontes. Haverá dois diretórios, um para o código da aplicação (src) e outro para os testes (srcTeste). Para efetuar a configuração, escolha Project|Properties, clique na opção Java Build Path no painel à esquerda e depois na aba Source à direita. Depois clique no botão Add Folder, digite "src" e clique em Ok.

Nesse momento o Eclipse irá perguntar se você deseja direcionar os arquivos compilados para o diretório bin. Aceite essa sugestão. Agora só falta adicionar o diretório srcTeste. Para isso, clique novamente no botão Add Folder e em seguida no botão Create New Folder e digite "srcTeste". Com isso, os diretórios onde serão armazenados os fontes estão configurados. 

Configurando o JUnit

Para executar testes automatizados, usaremos o JUnit. Para isso, é necessário adicionar a biblioteca junit.jar no classpath do projeto. Existem pelo menos duas formas de se fazer isso. A primeira é configurar o projeto para referenciar o junit.jar no diretório do plug-in do JUnit que já vem com o Eclipse. A outra é criar um diretório lib no projeto, copiar o junit.jar para esse diretório, e configurar o projeto para usá-lo.

...

Quer ler esse conteúdo completo? Tenha acesso completo