Finalmente chegamos na terceira – e última – parte da série “Integração contínua com Hudson e Delphi”.
Agora que já temos algum conhecimento básico do assunto e as ferramentas necessárias já estão instaladas, podemos finalmente colocar tudo em funcionamento.
Para poupar tempo, eu criei um projeto em Delphi sobre o qual poderemos trabalhar. Eu fiz em Delphi 2010, mas provavelmente não haverão grandes problemas em abrir em outras versões do Delphi (Quem encontrar alguma dificuldade pode entrar em contato comigo). Baixe o projeto aqui e descompacte-o na pasta DemoIC que você criou na segunda parte da série.
A integração contínua precisa que o build do projeto seja automatizado, e no momento nós não temos isso. Precisamos de um meio simples de executar o build em um único passo. Felizmente, o Delphi sempre teve um compilador de linha de comando, que poderia ser utilizado justamente para isso, e melhor ainda: Desde a versão 2007 ele trabalha em conjunto com o MSBuild, que é uma ferramenta de automação de builds da Microsoft, que torna o processo ainda mais fácil. Então tudo o que precisamos fazer é criar um script .bat que faça isso. Vamos lá:
- Crie um arquivo chamado Build.bat na sua pasta “DemoIC”.
- Abra o arquivo no Bloco de Notas e digite o seguinte código
@echo off
call "C:\Arquivos de programas\Embarcadero\RAD Studio\7.0\bin\rsvars.bat"
msbuild "Src\Calculadora.dproj" /p:configuration="Release"
- Salve o arquivo
Com isso, temos uma forma simples de executar o build do nosso projeto. Vamos explicar o conteúdo deste arquivo:
- A primeira linha serve para evitar que os outros comandos do script fiquem aparecendo na tela. É apenas uma questão visual, não interfere no funcionamento do script.
- A segunda linha chama um arquivo .bat que acompanha o Delphi. Ele ajusta algumas configurações antes que possamos chamar o MSBuild. Eu recomendo que você crie uma variável de ambiente no computador que aponte para a pasta de instalação do Delphi, e edite o script de build para invocar o rsvars.bat com base nesta variável. Isso permite que o mesmo script de build possa ser utilizado em diferentes máquinas, cada uma com o Delphi instalado em um lugar diferente.
- A terceira linha chama o MSBuild para finalmente compilar o projeto. Repare no parâmetro /p:configuration=”Release”. Você deve saber que os projetos no Delphi podem ter diferentes configurações de build, e este parâmetro serve justamente para especificarmos qual configuração será utilizada.
Agora, vamos adicionar estes arquivos no nosso sistema de controle de versão. Para isso, vá até a pasta DemoIC, selecione todos os arquivos e pastas exceto as pastas DCU, DCUTestes, Out e OutTestes. Clique com o botão direito do mouse em algum dos arquivos ou pastas que esteja selecionado, vá ao menu “TortoiseSVN”, e depois em “Add”.
Deve surgir uma tela como esta:

Remova a seleção das seguintes pastas e arquivos, pois eles não devem ser versionados:
- DemoCalculadora.groupproj.local
- Src/_history
- Src/Calculadora.dproj.local
- Src/Calculadora.identcache
- SrcTestes/__history
- SrcTestes/CalculadoraTests.dproj.local
- SrcTestes/CalculadoraTests.identcache
Feito isso, clique “OK”. Surgirá uma tela mostrando os arquivos adicionados, e clique “OK” nela tambem. Após isso, clique com o botão direito em alguma área livre da pasta “DemoIC” e clique em “SVN Commit”.
Na tela que se abre, clique “OK”, e depois “OK” na tela seguinte. Pronto, agora todos os fontes do nosso projeto estão no Subversion.
Agora vamos criar uma tarefa no Hudson. Criar uma tarefa é como cadastrar o projeto no Hudson para que este controle o build do projeto.
Vamos lá, abra o Hudson. A tela inicial dele deve ser a seguinte:

Localize, no lado esquerdo da tela, o item “Nova Tarefa” e clique nele.
Você deve ver esta tela agora:

No campo “Nome da tarefa”, informe “DemoIC” (sem as aspas).
Marque o item “Construir um projeto de software free-style”. Isso nos permitirá configurar livremente a rotina de build do projeto. O Hudson conta com outras opções, que não serão utilizadas aqui.
Muito bem, agora clique “OK”.
Na tela seguinte, temos que informar mais alguns parâmetros do projeto. Primeiro, temos que dizer qual servidor de gerenciamento de código fonte será utilizado: Então, localize o item “Gerenciamento de Código Fonte” e selecione “Subversion”.
Ao selecionar “Subversion”, alguns novos campos aparecerão na tela, vamos então configura-los: No campo “URL do Repositório”, informe “https://localhost/svn/DemoIC/trunk” (sem aspas), esse é o endereço para o repositório do projeto, contendo tambem o caminho da pasta onde estão os fontes que o Hudson irá baixar.
Em “Diretório do módulo local (opcional)”, informe “DemoIC”. Quando o Hudson faz o download dos arquivos do repositório, ele irá colocar os arquivos em uma pasta com o nome que foi especificado aqui. Caso não informemos nenhum valor, ele irá utilizar o último nome da URL do repositório, que no nosso caso seria “trunk”.
Muito bem, agora já informamos ao Hudson como ele fará para obter o código fonte do projeto. Agora precisamos informa-lo como ele fará para compilar o projeto. Para isso, localize um combo escrito “Add build step” e clique nele. Será aberto um menu com as seguintes opções:
- Executar shell
Instrui o Hudson a executar um comando de shell do Linux
- Invocar alvos Maven de alto nível
Faz com que o Hudson invoque o Maven para realizar o build
- Executar comando do Windows
Semelhante à primeira opção, mas serve para ser utilizada no Windows.
- Invocar ant
Faz com que o Hudson invoque o Ant para realizar o build
Utilizaremos a terceira opção. Após seleciona-la, deve surgir na sua tela um campo como este:

Este campo funciona da seguinte forma: O que você digitar nele, será gravado pelo Hudson em um arquivo .bat que estará localizado em uma pasta um nível acima da pasta “DemoIC” na qual o Hudson colocará os fontes do projeto ao construir o mesmo. Esse arquivo .bat criado pelo Hudson será executado quando for o momento de realizar algum build. Então o que temos que digitar ali é apenas o código necessario para executar o arquivo Build.bat dentro da pasta DemoIC. Então apenas digite o seguinte:
cd DemoIC
call Build.bat
Finalmente, clique em “Salvar”.
Para testar se está tudo correto, clique em “Construir Agora”, isso deverá iniciar um build do projeto.
Se tudo foi feito corretamente, você deverá ver uma tela como esta:

Repare na cor da bolinha no “Histórico de Construção”. Azul indica um build bem sucedido, enquanto vermelho indica o contrário.
Mas precisamos automatizar ainda mais o processo de build, pois isto deve ocorrer a cada commit do código fonte. Felizmente, o Hudson nos dá um mecanismo simples e eficiente de dispararmos o build de forma automatizada. Basta acessar a URL http://localhost:8080/hudson/job/DemoIC/build. Não é necessario nenhuma outra ação, apenas dar um GET nesta URL já faz com que um build seja disparado.
O Subversion nos dá outro recurso que será fundamental neste momento, são os chamados hooks. Hooks são comandos que você pode programar o Subversion para executar automaticamente em determinadas situações. No nosso caso, vamos utilizar um post-commit hook, onde poderemos definir uma ação a ser executada sempre após um commit.
Mas ainda falta uma peça neste quebra-cabeças: Como disparar um GET naquela URL do Hudson que mostrei anteriormente? Para fazer isso, eu uso esta ferramenta. Se preferir, aqui está um link direto para download.
Tendo baixado a ferramenta, coloque-a em uma pasta de sua preferência e renomeie o arquivo para wget.exe caso ele tenha vindo com outro nome. Não é necessário instalar. Após isso, coloque a pasta que você escolheu no path do Windows e reinicie o computador.
Muito bem, agora vamos configurar o hook:
- Abra o VisualSVN Server Manager.
- No painel da esquerda, localize o item “DemoIC” que está localizado um nivel abaixo do item “Repositories”.
- Clique com o botão direito em “DemoIC” e vá em “Properties”.
- Na tela que se abre, vá na aba “Hooks”.
- Clique sobre “Post-commit hook”.
- Clique em “Edit”.
- Na tela que se abre, digite o seguinte:
wget http://localhost:8080/hudson/job/DemoIC/build --spider
- Clique OK
- Clique OK novamente e feche o VisualSVN
Obs: O parâmetro
--spider
serve para que o wget não faça o download da URL especificada, mas sim apenas uma requisição GET no servidor. Isso evita tráfego de rede desnecessário.
Podemos fazer um teste agora. Abra o Delphi, e edite qualquer arquivo fonte do projeto de forma a introduzir um erro de compilação. Salve o projeto, vá na pasta e dê um commit no Subversion. Agora acesse o Hudson e clique na tarefa “DemoIC” para exibir as informações do nosso projeto. Neste momento, você deve estar vendo no “Histórico de construção” com uma bolinha vermelha, isto corresponde ao build que foi iniciado em função do commit que você acabou de fazer no Subversion. Agora vá no Delphi, desfaça a edição que você fez anteriormente e dê um novo commit.
Após isso, olhe novamente no Hudson, na página de informações do projeto “DemoIC” e você deve ter notado um terceiro item no “Histórico de construção”, desta vez sinalizando um build bem sucedido.
Bom, está quase tudo pronto. Mas ainda falta fazer com que o build teste o projeto, desta forma um build bem sucedido não será simplesmente um build sem erros de compilação, mas sim um build onde tudo foi compilado com sucesso E onde todos os testes automtizados passaram. O que precisamos fazer é editar no nosso Build.bat de forma a faze-lo compilar e executar o projeto de testes unitários, então vamos lá:
- Abra o arquivo Build.bat no bloco de notas.
- Acrescente o seguinte código ao final do arquivo
if %ERRORLEVEL% neq 0 Exit /b 1
msbuild "SrcTestes\CalculadoraTests.dproj" /p:configuration="BuildAutomatizado"
if %ERRORLEVEL% neq 0 Exit /b 1
call OutTestes\CalculadoraTests.exe
A primeira linha serve para terminar o script sinalizando uma condição de erro caso o passo anterior (isto é, a compilação do projeto principal) não tenha sido bem sucedido. A segunda linha irá compilar o projeto de testes unitários, e a terceira linha irá terminar o script sinalizando uma condição de erro caso a compilação dos testes unitários não tenha sido bem sucedida. Por fim, a última linha executa os testes unitários.
Note que para compilar os testes unitários, utilizei uma configuração de build chamada “BuildAutomatizado”, isso por que o projeto de testes unitários precisará ser compilado com algumas características especiais para poder ser efetivamente utilizado no nosso script de build, a saber:
- Precisa ser um aplicativo console.
- O aplicativo precisa retornar zero caso todos os testes passem, e retornar qualquer outro valor caso contrário.
Vamos então criar esta configuração. Abra o projeto CalculadoraTests no Delphi e crie uma nova configuração de build (Build configuration) para ele. Chame-a de “BuildAutomatizado”. No Delphi 2010, isso é feito no seguinte menu:

Agora vá nas opções da configuração BuildAutomatizado e defina os seguintes parâmetros:
- Conditional defines: CONSOLE_TESTRUNNER
- Unit output directory: ..\DCUTestes\
- Output directory: ..\OutTestes\
Agora abra o arquivo CalculadoraTests.dpr e modifique-o para ficar assim:
program CalculadoraTests;
{
Delphi DUnit Test Project
-------------------------
This project contains the DUnit test framework and the GUI/Console test runners.
Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
to use the console test runner. Otherwise the GUI test runner will be used by
default.
}
{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
Forms,
TestFramework,
GUITestRunner,
TextTestRunner,
UCalculadoraTests in 'UCalculadoraTests.pas';
{$R *.RES}
var
Results: TTestResult;
begin
Application.Initialize;
if IsConsole then
begin
Results := TextTestRunner.RunRegisteredTests;
try
if Results.FailureCount + Results.ErrorCount = 0 then
ExitCode := 0
else
ExitCode := 1;
finally
Results.Free;
end;
end
else
GUITestRunner.RunRegisteredTests;
end.
Basicamente, essas mudanças no dpr foram apenas para fazer o processo retornar o código 1 caso algum teste não tenha passado, e retornar 0 caso todos os testes tenham passado.
Feito isso, salve tudo, faça um commit no Subversion e observe o DemoIC no Hudson, deve ter sido gerado um novo build bem sucedido lá.
Agora vamos simular uma falha nos testes. Abra o arquivo UCalculadora.pas e adicione um “Exit;” logo após o begin no método TCalculadora.Calcular(). Ele ficará assim:
function TCalculadora.Calcular(A, B: Extended; Operacao: TOperacao): Extended;
begin
Exit;
case Operacao of
oAdicao: Result := A + B;
oSubtracao: Result := A - B;
oMultiplicacao: Result := A * B;
oDivisao: Result := A / B;
end;
end;
Salve, faça um commit e observe o DemoIC no Hudson. Você deverá ver um build falho agora. Se você clicar sobre o item correspondente a um build “Histórico de construção”, poderá acessar informações específicas sobre um determinado build. Por exemplo, em “Saída do console” você poderá visualizar o que foi gerado no console pelo script de build, isso é útil para identificar o ponto onde o build falhou.
Como pode ver, nós facilmente descobrimos um erro que foi introduzido “acidentalmente” no código, e então teremos a possibilidade de corrigi-lo rapidamente.
Uma coisa interessante, é que o nosso script de build (Build.bat) pode ser utilizado independente do Hudson. Se você mudar o servidor de integração contínua, poderá continuar utilizando. Ele serve inclusive para uso local. Exemplo: Você terminou uma implementação e quer ver se tudo está funcionando bem antes de enviar o código para o controle de versão? Basta executar o script de build.
Para terminar, farei algumas considerações que serão úteis quando você for utilizar na prática (eu espero que você o faça) o que leu aqui:
Eu instalei tudo em uma mesma máquina para simplificar as explicações, mas no mundo real não será assim. Considere que você possuirá os seguintes tipos de computadores no seu ambiente e eu vou explicar quais ferramentas seriam instaladas em cada um, dentre as que utilizamos nesta série:
- Máquinas de desenvolvimento: Onde os programadores trabalharão. Aqui normalmente seria instalado o Delphi e o cliente do Subversion (No nosso caso, o TortoiseSVN).
- Servidor de código fonte: Aqui é onde ficarão os fontes do projeto. Instale o servidor Subversion (No nosso caso o VisualSVN) e o WGet.
- Servidor de integração contínua: É onde ficará instalado o Hudson.
- Servidor de build: Onde os builds ocorrerão, precisa do Delphi instalado.
Sei que o Hudson suporta realizar builds em máquinas remotas, mas não sei configurar isso. Então para mim o servidor de integração e de build são um só. Pode ser interessante separar isso caso o seu sistema precise ser compilado/testado em diferentes plataformas. Assim você teria um servidor central de integração, que dispararia o build em diversas outras máquinas cada uma com uma plataforma diferente.
O servidor de integração e de código fonte podem ser na mesma máquina ou não, isso fica a seu critério.
O Hudson ainda tem muitos recursos. Por exemplo, ele pode ser configurado para enviar e-mails quando houver alguma mudança relevante no projeto. Ou seja, quando o projeto estava estável e de repente um build falhou, ou quando os builds não seram bem sucedidos e de repente um build passou a funcionar. Isso é importante para os membros da equipe saberem o estado do build sem terem que ficar monitorando o Hudson.
Ele tambem suporta plugins, para adicionar novas funcionalidades ao mesmo. A instalação de plugins é bem simples, dê uma olhada no menu “Gerenciar Hudson/Gerenciar plugins”.
Com isso, chegamos ao final desta série. Espero ter conseguido ser claro e mostrar as vantagens da prática da integração contínua e o quão simples é configurar um ambiente para começar a trabalhar desta forma.
11 Views Filed under:
Desenvolvimento by magnomp