<?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>Agile Hacking &#187; pt-br</title>
	<atom:link href="http://gabrielfalcao.com/category/pt-br/feed/" rel="self" type="application/rss+xml" />
	<link>http://gabrielfalcao.com</link>
	<description>The GNUs of mine, and its green builds</description>
	<lastBuildDate>Tue, 08 Jun 2010 13:22:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Apresentando Lettuce, BDD em python</title>
		<link>http://gabrielfalcao.com/2010/05/12/apresentando-lettuce-bdd-em-python/</link>
		<comments>http://gabrielfalcao.com/2010/05/12/apresentando-lettuce-bdd-em-python/#comments</comments>
		<pubDate>Wed, 12 May 2010 23:50:14 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[GNU]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[pt-br]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=175</guid>
		<description><![CDATA[Depois de muitas horas de hacking intenso, venho apresentar a primeira release candidate do Lettuce. Trata-se de uma ferramenta de BDD 100% baseada no Cucumber. O nome teve duas motivações: Lettuce (Alface) é um vegetal verde, assim como Cucumber (Pepino), a idéia é que os testes sempre estejam verdes Letuce é também o nome de [...]]]></description>
			<content:encoded><![CDATA[<h1><span style="font-weight: normal; font-size: 13px;">Depois de muitas horas de hacking intenso, venho apresentar a primeira release candidate do <a href="http://lettuce.it/">Lettuce</a>.</span></h1>
<p>Trata-se de uma ferramenta de <a href="http://pt.wikipedia.org/wiki/Behavior_Driven_Development">BDD</a> 100% baseada no <a href="http://cukes.info">Cucumber</a>.</p>
<p>O nome teve duas motivações:</p>
<ul>
<li>Lettuce (Alface) é um vegetal verde, assim como Cucumber (Pepino), a idéia é que os testes sempre estejam verdes <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li><a href="http://www.myspace.com/letuceletuce">Letuce</a> é também o nome de uma <a href="http://www.myspace.com/letuceletuce">banda</a> à qual tenho muita admiração.</li>
</ul>
<p style="text-align: center;"><a href="http://gabrielfalcao.com/wp-content/uploads/2010/05/screenshot-lettuce1.png"><img class="size-full wp-image-190  aligncenter" title="Lettuce rodando num Mac" src="http://gabrielfalcao.com/wp-content/uploads/2010/05/screenshot-lettuce1.png" alt="" width="490" height="301" /></a></p>
<h2>Mãos ao código</h2>
<p>Deixei links para a documentação no fim deste post, mas aqui vai uma prévia:</p>
<p>Funcionalidades são descritas em arquivos com a extensão <em>.feature</em>, e devem ficar por padrão, dentro do seu projeto, chamada<em> features</em></p>
<p><em>Por sua vez, features são descritas assim:</em></p>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Feature: Introduce lettuce to my friends<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">In</span> order to show it working<br />
&nbsp; As lettuce author<br />
&nbsp; I want to create a scenario that passes<br />
<br />
&nbsp; Scenario: Concatenate names<br />
&nbsp; &nbsp; Given I have the following names:<br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> name <span style="color:#006600; font-weight:bold;">|</span> surname <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> john <span style="color:#006600; font-weight:bold;">|</span> doe &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> ian &nbsp;<span style="color:#006600; font-weight:bold;">|</span> murdock <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">When</span> I join them<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">Then</span> I see the data:<br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> joined &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> Doe, John &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> Murdock, Ian <span style="color:#006600; font-weight:bold;">|</span></div></div>
<p>Para implementar as steps, basta criar um arquivo python qualquer dentro da pasta <em>features</em> o Lettuce importará todos eles recursivamente.<br />
Exemplo:</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:100%;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> lettuce <span style="color: #ff7700;font-weight:bold;">import</span> step<span style="color: #66cc66;">,</span> world<span style="color: #66cc66;">,</span> before<br />
<span style="color: #ff7700;font-weight:bold;">from</span> some_module <span style="color: #ff7700;font-weight:bold;">import</span> NameJoiner<br />
<br />
<span style="color: #808080; font-style: italic;"># setup</span><br />
<span style="color: #66cc66;">@</span>before.<span style="color: black;">each_scenario</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> set_joined<span style="color: black;">&#40;</span>scenario<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; world.<span style="color: black;">joined</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># steps</span><br />
<span style="color: #66cc66;">@</span>step<span style="color: black;">&#40;</span><span style="color: #483d8b;">'I have the following names'</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> set_names<span style="color: black;">&#40;</span>step<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; world.<span style="color: black;">people</span> <span style="color: #66cc66;">=</span> step.<span style="color: black;">hashes</span><br />
<br />
<span style="color: #66cc66;">@</span>step<span style="color: black;">&#40;</span><span style="color: #483d8b;">'join them'</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> join_names<span style="color: black;">&#40;</span>step<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> person <span style="color: #ff7700;font-weight:bold;">in</span> world.<span style="color: black;">people</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; joiner <span style="color: #66cc66;">=</span> NameJoiner<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name<span style="color: #66cc66;">=</span>person<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surname<span style="color: #66cc66;">=</span>person<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;surname&quot;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; world.<span style="color: black;">joined</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>joiner.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #66cc66;">@</span>step<span style="color: black;">&#40;</span><span style="color: #483d8b;">'I see the data'</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> check_names<span style="color: black;">&#40;</span>step<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> name<span style="color: #66cc66;">,</span> data <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>world.<span style="color: black;">joined</span><span style="color: #66cc66;">,</span> step.<span style="color: black;">hashes</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> name <span style="color: #66cc66;">==</span> data<span style="color: black;">&#91;</span><span style="color: #483d8b;">'joined'</span><span style="color: black;">&#93;</span></div></div>
<p>(baixe o exemplo completo <a href="http://gabrielfalcao.com/wp-content/uploads/2010/05/lettuce-example.zip">aqui</a>)</p>
<h1>Motivação</h1>
<p>Desde que comecei a praticar <a href="http://pt.wikipedia.org/wiki/Test_Driven_Development">TDD</a> em <a href="http://python.org">Python</a> tive várias experiências, testei várias bibliotecas de <a href="http://pt.wikipedia.org/wiki/Mock_Object">mock</a> e técnicas de teste.<br />
Em projetos de aplicações web usei o <a href="http://wiki.github.com/heynemann/pyccuracy/">Pyccuracy</a>, assim podia descrever o <a href="http://pt.wikipedia.org/wiki/Behavior_Driven_Development">comportamento</a> da aplicação ao mesmo tempo que fazia testes automatizados da interface.</p>
<p>No entanto, tive a chance de testar o  <a href="http://cukes.info">Cucumber</a> num projeto <a href="http://djangoproject.com">Django</a> aqui na <a href="http://globo.com">globo.com</a>, me apaixonei por funcionalidades incrivelmente produtivas, como <a href="http://wiki.github.com/aslakhellesoy/cucumber/multiline-step-arguments"><em>step tables</em></a> que permite desenhar uma tabela com caracteres, e mapear como lista de hashes, bem como <a href="http://wiki.github.com/aslakhellesoy/cucumber/scenario-outlines">scenario outlines</a>.</p>
<p>Daí veio a grande inspiração: implementar uma ferramenta como o Cucumber, mas em python puro.</p>
<p>Por que?<br />
Para programadores python, é mais cômodo usar bibliotecas em python puro. Eu pessoalmente evito misturar linguagens, a não ser que a melhor solução seja realmente em outra linguagem.</p>
<p>Cucumber é, na minha opinião, uma lib que torna ruby ainda mais sexy <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Criar uma aplicação robusta, bem testada requer paciência, que tal tornar isso mais divertido ?<br />
É mais fácil empacotar módulos python para debian/ubuntu <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Além disso, apesar de <a href="http://wiki.github.com/aslakhellesoy/cucumber/python">Cucumber dar suporte a Python</a>, seria interessante usar python puro dentro das step definitions.<br />
Supondo o desenvolvimento de uma aplicação Django com cucumber, seria útil manipular os models dentro de step definitions. Entretanto, para isso acontecer, é necessário usar algo como <a href="http://rubyforge.org/projects/rubypython">rubypython</a>, cuja última release data outubro de 2009.</p>
<h2>Exemplos de bibliotecas similares/equivalentes entre python e ruby</h2>
<p><strong>Framework web:</strong></p>
<pre>ruby: <a href="http://rubyonrails.org/">rails
</a>python: <a href="http://djangoproject.com">django</a></pre>
<h3>Micro-framework web:</h3>
<pre>ruby: <a href="http://sinatrarb.com">sinatra
</a>python: <a href="http://cherrypy.org">cherrypy</a></pre>
<h3>Deploy automatizado:</h3>
<pre>ruby: <a href="http://capify.org">capistrano
</a>python: <a href="http://fabfile.org">fabric</a></pre>
<h3>Behaviour-driven development:</h3>
<pre>ruby: <a href="http://cukes.info">cucumber
</a>python: <a href="http://lettuce.it">lettuce</a> ?! (quem sabe <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</pre>
<h1>Direto ao assunto!</h1>
<p>Hoje estou liberando oficialmente a primeira release candidate do Lettuce, que atualmente possui as seguintes features:</p>
<ul>
<li>Hooks pre/pós execução de:
<ul>
<li>Toda a suíte de testes</li>
<li>Cada feature</li>
<li>Cada scenario</li>
<li>Cada step</li>
</ul>
</li>
<li>Contexto global: world</li>
<li>Scenario outlines</li>
<li>Step tables</li>
<li>Nomes e formato de arquivo de features compatível com cucumber</li>
<li>Output colorido</li>
<li>Output sem cor</li>
</ul>
<p>Mas&#8230; O que falta para fechar a primeira release oficial? Além de ter feedback sobre possíveis bugs das features já implementadas para melhorá-las, a intenção é que a primeira release também tenha as seguintes funcionalidades:</p>
<ul>
<li><a href="http://github.com/gabrielfalcao/lettuce/issues#issue/12">Suporte a features escritas em português</a></li>
<li><a href="http://github.com/gabrielfalcao/lettuce/issues#issue/28">Tratamento de KeyboardInterruption</a></li>
<li><a href="http://lettuce.it">Documentação completa</a></li>
</ul>
<h2>Documentação</h2>
<p>Não poderia faltar, mas ainda está sendo escrita.<br />
De qualquer forma, já possui o básico para colocar o um novo projeto funcionando. E se você já conhece o Cucumber, não terá dificuldades.</p>
<p><a href="http://lettuce.it">Acesse a documentação aqui</a></p>
<p>Ou melhor ainda, vá direto ao <strong><a href="http://lettuce.it/intro/quickstart.html#intro-quickstart">&#8220;quick start&#8221;</a></strong></p>
<h2>Contribua!</h2>
<p>Estou sedento por feedbacks (negativos e positivos), sendo assim:</p>
<ul>
<li><a href="http://github.com/gabrielfalcao/lettuce">Obtenha o código no repositório git</a></li>
<li>Junte-se à <a href="http://groups.google.com/group/lettuce-users">lista de discussão de usuários do lettuce</a></li>
<li><a href="http://github.com/gabrielfalcao/lettuce/issues">Acesse o bugtracker !</a></li>
</ul>
<p>Por fim, o lettuce está sob GNU GPL 3+ e ainda tem um longo caminho pela frente. Toda forma de ajuda é bem vinda, seja com patches, documentação, suporte para outros idiomas, etc.</p>
<p>Happy hacking <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2010/05/12/apresentando-lettuce-bdd-em-python/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

