<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DestaqueBlog &#187; unittest</title>
	<atom:link href="http://weblog.destaquenet.com/tag/unittest/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Integração Contínua de aplicações Python com Hudson</title>
		<link>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/</link>
		<comments>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 12:00:24 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[integração contínua]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testes]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[unittest]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=166</guid>
		<description><![CDATA[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, &#8230; <a href="http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No começo deste mês <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">eu dei dicas</a> sobre como usar o <a href="http://www.nongnu.org/fab/">Fabric</a> para automatizar o <em>build</em> e o <em>deployment</em> de aplicações <a href="http://python.org/">Python</a>.</p>
<p>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 <a href="http://martinfowler.com/articles/continuousIntegration.html">deste artigo</a>, até porque este <em>post</em> terá um enfoque mais prático.</p>
<p>Neste texto será mostrado como configurar um projeto Python no <a href="http://hudson.dev.java.net/">Hudson</a>, 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 <a href="http://git.or.cz/">Git</a>, mas usuários de outros sistemas também poderão achar este texto útil.<span id="more-166"></span></p>
<h3>Baixando o Hudson</h3>
<p>Acesse o site do <a href="http://hudson.dev.java.net/">Hudson</a> e baixe o arquivo <code>.war</code> 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 <code>8080</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">java <span style="color: #660033;">-jar</span> hudson.war</pre></div></div>

<div id="attachment_185" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01-300x187.png" alt="Tela inicial do Hudson" title="Tela inicial do Hudson" width="300" height="187" class="size-medium wp-image-185" /></a><p class="wp-caption-text">Tela inicial do Hudson</p></div>
<p>Perca uns cinco minutos dando uma navegada no Hudson para ter uma idéia melhor do que é possível de ser feito com ele.</p>
<h3>Hudson e plugins</h3>
<p>O Hudson vem com suporte a <a href="http://maven.apache.org/">Maven</a> e <a href="http://ant.apache.org/">Ant</a>, duas das mais populares ferramentas para <em>build</em> de aplicações Java. Mas não se engane: o Hudson pode ser aproveitado em praticamente qualquer projeto, independente da linguagem e dos <em>frameworks</em> utilizados.</p>
<p>As funcionalidades do Hudson podem ser estendidas através de <em>plugins</em>, sendo que neste artigo utilizaremos dois deles: o <em>Git Plugin</em>, necessário para que o Hudson consiga trabalhar com repositórios Git, e o <em>Violations</em>, que consegue interpretar a saída de diferentes verificadores de código (dentre eles o <a href="http://www.logilab.org/857">pylint</a>, um analisador de código Python!) e exibir informações a respeito da qualidade do código-fonte.</p>
<p>Para instalar esses plugins, basta acessar a tela de gerenciamento de plugins, marcar o <em>Git Plugin</em> e o <em>Violations</em>, e confirmar:</p>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02-300x187.png" alt="Instalando os plugins" title="Instalando os plugins" width="300" height="187" class="size-medium wp-image-186" /></a><p class="wp-caption-text">Instalando os plugins</p></div>
<p>Assim que a instalação terminar, reinicie o Hudson.</p>
<h3>Integrando testes escritos com PyUnit ao Hudson</h3>
<p>Apesar de existirem várias opções para criação e execução de testes unitários para Python, o <a href="http://pyunit.sourceforge.net/">PyUnit</a> costuma ser o mais usado pelo fato de já estar incluído na distribuição padrão do Python.</p>
<p>Quem já fuçou no código do PyUnit sabe que ele define <strong>apenas um</strong> <code>TestRunner</code>, o <a href="http://pyunit.sourceforge.net/pyunit.html#RUNNING_INT"><code>TextTestRunner</code></a>. O que este <code>TestRunner</code> basicamente faz é gerar em um fluxo qualquer (geralmente no <code>sys.stderr</code>) uma saída parecida com a seguinte:</p>
<pre>.....
----------------------------------------------------------------------
Ran 5 tests in 0.067s</pre>
<p>Apesar de eu me contentar com essa saída mais simples, bom, ferramentas como o próprio Hudson <strong>não se contentam</strong>; elas preferem algo como o bom e velho XML, que, convenhamos, é muito mais fácil de parsear.</p>
<p>Perdi algumas horas na Internet procurando por um <code>TestRunner</code> 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 <code>TestRunner</code>: <a href="http://github.com/danielfm/unittest-xml-reporting/tree">XMLTestRunner</a>. O código deste &#8220;projeto&#8221;, disponibilizado no <a href="http://github.com/">Github</a>, contém instruções de uso e scripts de exemplo. <strong>Clonem e forkem à vontade!</strong></p>
<p>Antes de prosseguirmos, baixe o módulo <code>xmlrunner.py</code> do <a href="http://github.com/danielfm/unittest-xml-reporting/tree">site do projeto</a> e o copie em algum lugar dentro do seu <code>PYTHONPATH</code>.</p>
<h3>Integrando um projeto Python no Hudson</h3>
<p>Para não perdermos tempo criando do zero um projeto de exemplo em Python, eu mostrarei como fazer para integrar o próprio <code>XMLTestRunner</code> com o Hudson.</p>
<p>Abra o console administrativo do Hudson e clique no link <em>New Job</em>:</p>
<div id="attachment_214" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03-300x172.png" alt="Criando um projeto &quot;free-style&quot;" title="Criando um projeto &quot;free-style&quot;" width="300" height="172" class="size-medium wp-image-214" /></a><p class="wp-caption-text">Criando um projeto &quot;free-style&quot;</p></div>
<p>Na próxima tela, precisamos configurar o Job com os dados necessários:</p>
<div id="attachment_215" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-215" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<div id="attachment_216" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-216" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<p>Isso é tudo! Confirme as alterações e clique no link <em>Build now</em>. Aguarde alguns segundos enquanto o projeto é baixado do repositório Git e testado:</p>
<div id="attachment_220" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06-300x172.png" alt="Exemplos de builds feitos pelo Hudson" title="Exemplos de builds feitos pelo Hudson" width="300" height="172" class="size-medium wp-image-220" /></a><p class="wp-caption-text">Exemplos de builds feitos pelo Hudson</p></div>
<div id="attachment_238" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07-300x172.png" alt="Relatório de execução de testes" title="Relatório de execução de testes" width="300" height="172" class="size-medium wp-image-238" /></a><p class="wp-caption-text">Relatório de execução de testes</p></div>
<div id="attachment_239" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08-300x172.png" alt="Análise de código feita pelo pylint" title="Análise de código feita pelo pylint" width="300" height="172" class="size-medium wp-image-239" /></a><p class="wp-caption-text">Análise de código feita pelo pylint</p></div>
<h3>Como disparar o <em>build</em> de forma automática?</h3>
<p>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 <em>build</em> sempre que alguém modificar código no repositório.</p>
<p>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 <em>build</em> deve ser feito; a segunda alternativa é apenas disparar o <em>build</em> quando alguém modificar código no repositório.</p>
<p>Como acontece com outros sistemas de controle de revisão, o Git possui <em>hooks</em> que nos permite executar ações em determinados momentos. Esses <em>hooks</em> nada mais são do que scripts executáveis localizados no diretório <code>.git/hooks</code>.</p>
<p>Mas enfim, quando disparar o <em>build</em>? 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 <em>build</em> periodicamente. Para isso, você deve configurar um ou mais <em>Build Triggers</em>, na tela de configuração do Job.</p>
<p>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 <em>hooks</em> como ferramenta de integração entre o repositório Git e o Hudson.</p>
<p>Agora a pergunta que não quer calar: <strong>como integrar o Git e o Hudson?</strong> Bem, isso ficará como exercício para o leitor.</p>
<p>Dicas:</p>
<ul>
<li>O Hudson <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Remote+access+API">disponibiliza uma API</a> através da qual se pode agendar <em>builds</em>, alterar as configurações do Job, criar Jobs, entre outras coisas.</li>
<li>Para conhecer os <em>hooks</em> oferecidos pelo Git, consulte a <a href="http://www.kernel.org/pub/software/scm/git/docs/githooks.html">documentação</a>.</li>
</ul>
<h3>Conclusão</h3>
<p>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.</p>
<p>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, <em>framework</em> de testes que eu costumo utilizar, não oferece uma forma de gerar relatórios XML, da mesma forma que Ant e Maven fazem.</p>
<p>Depois de estudar o funcionamento interno do PyUnit, eu decidi implementar um <code>TestRunner</code> 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.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

