No começo deste mês eu dei dicas sobre como usar o Fabric para automatizar o build e o deployment de aplicações Python.
Essa automatização por si só já quebra uma árvore, mas ela possibilita ainda o uso de Integração Contínua, uma prática extremamente importante que costuma ajudar muitas equipes a manter seus projetos nos trilhos. Para mais informações sobre Integração Contínua, eu recomendo a leitura deste artigo, até porque este post terá um enfoque mais prático.
Neste texto será mostrado como configurar um projeto Python no Hudson, um servidor de Integração Contínua muito simples de configurar e utilizar. O sistema de controle de versões que eu utilizo aqui é o Git, mas usuários de outros sistemas também poderão achar este texto útil.
Baixando o Hudson
Acesse o site do Hudson e baixe o arquivo .war através do link disponível na página principal. Quando o download terminar, basta rodar o comando abaixo para subir o servidor na porta 8080:
java -jar hudson.warPerca uns cinco minutos dando uma navegada no Hudson para ter uma idéia melhor do que é possível de ser feito com ele.
Hudson e plugins
O Hudson vem com suporte a Maven e Ant, duas das mais populares ferramentas para build de aplicações Java. Mas não se engane: o Hudson pode ser aproveitado em praticamente qualquer projeto, independente da linguagem e dos frameworks utilizados.
As funcionalidades do Hudson podem ser estendidas através de plugins, sendo que neste artigo utilizaremos dois deles: o Git Plugin, necessário para que o Hudson consiga trabalhar com repositórios Git, e o Violations, que consegue interpretar a saída de diferentes verificadores de código (dentre eles o pylint, um analisador de código Python!) e exibir informações a respeito da qualidade do código-fonte.
Para instalar esses plugins, basta acessar a tela de gerenciamento de plugins, marcar o Git Plugin e o Violations, e confirmar:
Assim que a instalação terminar, reinicie o Hudson.
Integrando testes escritos com PyUnit ao Hudson
Apesar de existirem várias opções para criação e execução de testes unitários para Python, o PyUnit costuma ser o mais usado pelo fato de já estar incluído na distribuição padrão do Python.
Quem já fuçou no código do PyUnit sabe que ele define apenas um TestRunner, o TextTestRunner. O que este TestRunner basicamente faz é gerar em um fluxo qualquer (geralmente no sys.stderr) uma saída parecida com a seguinte:
..... ---------------------------------------------------------------------- Ran 5 tests in 0.067s
Apesar de eu me contentar com essa saída mais simples, bom, ferramentas como o próprio Hudson não se contentam; elas preferem algo como o bom e velho XML, que, convenhamos, é muito mais fácil de parsear.
Perdi algumas horas na Internet procurando por um TestRunner que conseguisse gerar arquivos XML no mesmo formato que os gerados pelo Ant e Maven, mas não encontrei nenhuma opção que fosse minimamente confiável. Por isso, eu tomei a liberdade de escrever meu próprio TestRunner: XMLTestRunner. O código deste “projeto”, disponibilizado no Github, contém instruções de uso e scripts de exemplo. Clonem e forkem à vontade!
Antes de prosseguirmos, baixe o módulo xmlrunner.py do site do projeto e o copie em algum lugar dentro do seu PYTHONPATH.
Integrando um projeto Python no Hudson
Para não perdermos tempo criando do zero um projeto de exemplo em Python, eu mostrarei como fazer para integrar o próprio XMLTestRunner com o Hudson.
Abra o console administrativo do Hudson e clique no link New Job:
Na próxima tela, precisamos configurar o Job com os dados necessários:
Isso é tudo! Confirme as alterações e clique no link Build now. Aguarde alguns segundos enquanto o projeto é baixado do repositório Git e testado:
Como disparar o build de forma automática?
Uma vez que o projeto tenha sido configurado corretamente, basta um clique do mouse para que o Hudson faça todo o trabalho sujo. O problema agora é lembrar de fazer o build sempre que alguém modificar código no repositório.
Felizmente, temos duas opções para nos livrar de mais essa tarefa manual: a primeira seria configurar, nas propriedades do Job, uma expressão Cron que indique de quanto em quanto tempo o build deve ser feito; a segunda alternativa é apenas disparar o build quando alguém modificar código no repositório.
Como acontece com outros sistemas de controle de revisão, o Git possui hooks que nos permite executar ações em determinados momentos. Esses hooks nada mais são do que scripts executáveis localizados no diretório .git/hooks.
Mas enfim, quando disparar o build? Se o repositório Git e o servidor Hudson não são capazes de se comunicar diretamente, talvez a única alternativa seja disparar o build periodicamente. Para isso, você deve configurar um ou mais Build Triggers, na tela de configuração do Job.
Entretanto, se você mantém o repositório Git e o servidor Hudson na mesma máquina, ou mesmo em máquinas diferentes mas capazes de se comunicar via rede, podemos considerar a utilização dos hooks como ferramenta de integração entre o repositório Git e o Hudson.
Agora a pergunta que não quer calar: como integrar o Git e o Hudson? Bem, isso ficará como exercício para o leitor.
Dicas:
- O Hudson disponibiliza uma API através da qual se pode agendar builds, alterar as configurações do Job, criar Jobs, entre outras coisas.
- Para conhecer os hooks oferecidos pelo Git, consulte a documentação.
Conclusão
Já faz algum tempo que eu venho utilizando o Hudson para integrar projetos Java, e esta ferramenta vem se mostrando muito útil no meu dia-a-dia. Só quem pratica Integração Contínua sabe o quanto é complicado não contar com a segurança que ela proporciona ao desenvolvimento.
O problema, no entanto, começou quando eu optei pelo Python em vez do Java em certos projetos. Obviamente, eu queria aproveitar o ambiente de Integração Contínua que eu já utilizava, o que foi bastante complicado já que o PyUnit, framework de testes que eu costumo utilizar, não oferece uma forma de gerar relatórios XML, da mesma forma que Ant e Maven fazem.
Depois de estudar o funcionamento interno do PyUnit, eu decidi implementar um TestRunner que fosse capaz de gerar arquivos XML no formato esperado pelo Hudson. Deu um bocado de trabalho, é verdade, mas pelo menos agora eu consigo utilizar os excelentes relatórios gerados pelo Hudson para acompanhar a execução dos meus testes PyUnit.
Como o Brasil é grande, seria burrice achar que eu fui o único a enfrentar esse tipo de dificuldade. Por esse motivo, eu resolvi escrever este texto e, quem sabe, ajudar àqueles que enfrentam um problema semelhante.
Veja também:
- Deployment de aplicações Python com Fabric
- Debugando aplicações JavaEE no Glassfish v2
- 2 (boas) formas de testar clientes JavaMail
- VPN PPTP no Ubuntu Intrepid
- Test Driven Development com Java Swing
Tags: build, configuração, hudson, integração contínua, java, open source, plugin, projeto, python, testes, tutorial, unittest







