<?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; Python</title>
	<atom:link href="http://gabrielfalcao.com/category/programming/python/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>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>lettuce 0.1 official release</title>
		<link>http://gabrielfalcao.com/2010/06/08/lettuce-0-1-official-release/</link>
		<comments>http://gabrielfalcao.com/2010/06/08/lettuce-0-1-official-release/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 04:40:41 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Free Software]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=211</guid>
		<description><![CDATA[27 days after its first release candidate, lettuce is now much mature and also got new features.
Lettuce is a BDD tool written in python, 100% based on cucumber.
There are two reasons for the name:

Lettuce is a green vegetable, just like cucumber the idea is that your tests must be always green.
Letuce is the name of a [...]]]></description>
			<content:encoded><![CDATA[<p>27 days after its <a href="http://gabrielfalcao.com/2010/05/12/apresentando-lettuce-bdd-em-python/">first</a> release candidate, <a href="http://lettuce.it">lettuce</a> is now much mature and also got new features.</p>
<p>Lettuce is a <a href="http://pt.wikipedia.org/wiki/Behavior_Driven_Development">BDD</a> tool written in python, 100% based on <a href="http://lettuce.it">cucumber</a>.</p>
<p>There are two reasons for the name:</p>
<ul>
<li>Lettuce is a green vegetable, just like cucumber the idea is that your tests must be always green.</li>
<li><a href="http://www.myspace.com/letuceletuce">Letuce</a> is the name of a brazillian band that I pretty much like</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>Hands on!</h2>
<p>There are links to lettuce&#8217;s official documentation at the end of this post, but there is a sneak peak:</p>
<p><a href="http://lettuce.it/reference/features.html#lettuce-feature">Features</a> are described in files with <em>.feature </em>extension and must be, by defaul within your project, in a folder called &#8220;<em>features</em>&#8220;.</p>
<p><em>Features are described like this:</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     <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> ian  <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       <span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">|</span> Doe, John    <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>In order to define steps all you need to do is write a new python file wihin <em>features</em> folder, Lettuce will import them all, recursively.</p>
<p>Example:</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, world, 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 />
@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; world.<span style="color: black;">joined</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 />
@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; world.<span style="color: black;">people</span> = step.<span style="color: black;">hashes</span><br />
<br />
@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; <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; joiner = NameJoiner<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; name=person<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; surname=person<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;surname&quot;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span><br />
&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 />
@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; <span style="color: #ff7700;font-weight:bold;">for</span> name, 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>, step.<span style="color: black;">hashes</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> name == data<span style="color: black;">&#91;</span><span style="color: #483d8b;">'joined'</span><span style="color: black;">&#93;</span></div></div>
<p>(the full example is available here <a href="http://gabrielfalcao.com/wp-content/uploads/2010/05/lettuce-example.zip">aqui</a>)</p>
<h1>Motivation</h1>
<p>Since I started with <a href="http://pt.wikipedia.org/wiki/Test_Driven_Development">TDD</a> in <a href="http://python.org">Python</a> I had many experiences, I&#8217;ve tested many mock <a href="http://pt.wikipedia.org/wiki/Mock_Object">mock</a> libraries and test techniques.<br />
In web projects I&#8217;ve used <a href="http://wiki.github.com/heynemann/pyccuracy/">Pyccuracy</a>, so that I could both describe <a href="http://pt.wikipedia.org/wiki/Behavior_Driven_Development">behaviour</a> of the application and make automated acceptance tests.</p>
<p>Althrough, I had a chance to try <a href="http://cukes.info">Cucumber</a> with <a href="http://djangoproject.com">Django</a> here at <a href="http://globo.com">globo.com</a>, and the result was: I fell in love with it, and had incredibly productive features, such as <a href="http://wiki.github.com/aslakhellesoy/cucumber/multiline-step-arguments"><em>step tables</em></a> which allows drawing a ascii table and map it into a list of hashes, and the <a href="http://wiki.github.com/aslakhellesoy/cucumber/scenario-outlines">scenario outlines</a>.</p>
<p>From there I had THE inspiration: to implement a tool that works exactly like <a href="http://cukes.info">Cucumber</a>, but in python.</p>
<p>Why ?</p>
<p>Python programmers it&#8217;s easier and frictionless to use libraries written in Python. I personally avoid mixing programming languages in a single project, some technologies can suit perfectly in the project, no matter in what language, but if there is a Python option, I will give it a go.</p>
<p>Cucumber IMHO one lib to make ruby even more &#8220;sexy&#8221; <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Build a robust application, well tested required patience, what about turn it into fun ! ?<br />
It&#8217;s easier to package python modules for debian/ubuntu.</p>
<p>Besides, even considering the fact that  <a href="http://wiki.github.com/aslakhellesoy/cucumber/python">Cucumber already supports</a>, would be more interesting to user pure python within step definitions.<br />
Supposing that a web application will be written with Django and Cucumber, would be very useful to manipulate models within step definitions. However turning it possible, would need efforts to run <a href="http://rubyforge.org/projects/rubypython">rubypython</a>, which the latest release dates october 2009.</p>
<h2>Examples of similar libraries between python and ruby</h2>
<p><strong>Web framework:</strong></p>
<pre>ruby: <a href="http://rubyonrails.org/">rails
</a>python: <a href="http://djangoproject.com">django</a></pre>
<h3>Micro web framework:</h3>
<pre>ruby: <a href="http://sinatrarb.com">sinatra
</a>python: <a href="http://cherrypy.org">cherrypy</a></pre>
<h3>Automated deploy:</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> ?! (maybe ?! Who knows ?! <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</pre>
<h1>More on lettuce</h1>
<p><strong>Documentation</strong></p>
<p>Available at <a href="http://lettuce.it">http://lettuce.it</a> covers all supported features until now.</p>
<h2>Contribute!</h2>
<p>I&#8217;ll appreciate all kinds of feedback, to do so we have some channels:</p>
<ul>
<li><a href="http://github.com/gabrielfalcao/lettuce">GitHub repository</a></li>
<li>Junte-se à <a href="http://groups.google.com/group/lettuce-users">lettuce users mailing list</a></li>
<li><a href="http://github.com/gabrielfalcao/lettuce/issues">bugtracker !</a></li>
</ul>
<p>Lettuce is under GNU GPL 3+ and have a long way until get robust, and any kind of help is welcome: patches, documentation, language support and so on!</p>
<p><a href="http://lettuce.it/#lettuce-getting-involved">Grab it</a>, and 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/06/08/lettuce-0-1-official-release/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<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[Python]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[pt-br]]></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 uma banda [...]]]></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, world, 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 />
@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: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># steps</span><br />
@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> = step.<span style="color: black;">hashes</span><br />
<br />
@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 = NameJoiner<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name=person<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surname=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 />
@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, 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>, 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 == 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>
		<item>
		<title>Playing with ANSI colors and python with Couleur</title>
		<link>http://gabrielfalcao.com/2010/04/19/playing-with-ansi-colors-and-python-with-couleur/</link>
		<comments>http://gabrielfalcao.com/2010/04/19/playing-with-ansi-colors-and-python-with-couleur/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 15:50:24 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[GNU]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=150</guid>
		<description><![CDATA[Last night I&#8217;ve just released the first version of Couleur, which is (or at least try to be) a simple and awesome tool for using ANSI colors with python.
Couleur indeed turns very easy to handle shell colors in python.
In action
import time
import couleur

sh = couleur.Shell&#40;linebreak=True&#41;
for mood in &#91;&#34;bad&#34;, &#34;awful&#34;, &#34;normal&#34;, &#34;nice&#34;, &#34;awesome&#34;&#93;:
&#160; sh.red_on_black&#40;mood, replace=True&#41;
&#160; time.sleep&#40;1&#41;
Couleur creates [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I&#8217;ve just released the first version of <em><a href="http://github.com/gabrielfalcao/couleur">Couleur</a></em>, which is (or at least try to be) a simple and awesome tool for using ANSI colors with python.</p>
<p>Couleur indeed turns very easy to handle shell colors in python.</p>
<h2>In action</h2>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> couleur<br />
<br />
sh = couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> mood <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;bad&quot;</span>, <span style="color: #483d8b;">&quot;awful&quot;</span>, <span style="color: #483d8b;">&quot;normal&quot;</span>, <span style="color: #483d8b;">&quot;nice&quot;</span>, <span style="color: #483d8b;">&quot;awesome&quot;</span><span style="color: black;">&#93;</span>:<br />
&nbsp; sh.<span style="color: black;">red_on_black</span><span style="color: black;">&#40;</span>mood, replace=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
&nbsp; <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></div></div>
<p>Couleur creates colored output dinamically, so that you can mix colors and modifiers at will:</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> couleur<br />
sh = couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
sh.<span style="color: black;">bold_black_and_bold_yellow_on_red</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Gray | Yellow&quot;</span><span style="color: black;">&#41;</span></div></div>
<p>And even use &#8220;static&#8221; output, let&#8217;s simulate the output of a &#8220;git clone&#8221;:</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> couleur<br />
<br />
sh = couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">101</span><span style="color: black;">&#41;</span>:<br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span><br />
&nbsp; sh.<span style="color: black;">normal_and_bold_green</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;Counting objects: |%d%%&quot;</span> <span style="color: #66cc66;">%</span> x, <br />
&nbsp; &nbsp; replace=<span style="color: #008000;">True</span><br />
&nbsp; <span style="color: black;">&#41;</span><br />
&nbsp; <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0.08</span><span style="color: black;">&#41;</span></div></div>
<h2>Installation</h2>
<div class="codecolorer-container bash vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">user<span style="color: #000000; font-weight: bold;">@</span>machine:~$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> pip <span style="color: #c20cb9; font-weight: bold;">install</span> couleur</div></div>
<h2>Full Documentation</h2>
<p>Available <a href="http://github.com/gabrielfalcao/couleur/blob/master/README.md" target="_self">here</a></p>
<h2>Contributing</h2>
<p>Fork me on <a href="http://github.com/gabrielfalcao/couleur">github</a>, write tests, write code, make it pass, send a pull request <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/04/19/playing-with-ansi-colors-and-python-with-couleur/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New projects + agile = releases</title>
		<link>http://gabrielfalcao.com/2009/07/05/new-projects-agile-releases/</link>
		<comments>http://gabrielfalcao.com/2009/07/05/new-projects-agile-releases/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 20:50:31 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Free Software]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=113</guid>
		<description><![CDATA[When I lived in Belo Horizonte/MG, I used to make hack parties with some friends of mine (nothing to say about all those pizzas and beer).
The hack parties had no specific goal, but a main idea: Hack some free software, and share the knowledge.
Many of us, but specifically Lincoln and I, used to create new [...]]]></description>
			<content:encoded><![CDATA[<p>When I lived in Belo Horizonte/MG, I used to make hack <a href="http://leoserra.iaaeee.org/">parties</a> <a href="http://lincoln.alfaiati.net/">with</a> <a href="http://cascardo.info/">some</a> <a href="http://blog.kov.eti.br/">friends</a> <a href="http://fujii.iaaeee.org/diario/">of</a> <a href="http://metaldot.alucinados.com/">mine</a> (nothing to say about all those pizzas and beer).</p>
<p>The hack parties had no specific goal, but a main idea: Hack some free software, and share the knowledge.</p>
<p>Many of us, but specifically Lincoln and I, used to create new projects in every hack party,but only a handful of those were actually released. It was often matter for jokes like: &#8220;Oh, you are up to raise the &#8220;too many projects&#8221; exception&#8221;.</p>
<p>I have two words for that fact: &#8220;not agile&#8221;.</p>
<p>Our projects were often <a href="http://en.wikipedia.org/wiki/Proof_of_concept">POCs</a>, and we had no culture of TDD, short releases and so on.</p>
<p>But since I started to work at <a href="http://globo.com">Globo.com</a>, I learned so much about agile, specially Scrum. And some months ago I&#8217;ve just accomplished what I call as &#8220;agile feeling&#8221;.</p>
<p>I mean, it&#8217;s a feeling that I can deliver software with quality in a short period of time.</p>
<p>But how ?</p>
<p>The idea is quite simple, you just have to follow some principles:</p>
<h2>Think simple</h2>
<p>This basically means focusing at the problem at hand, never trying to solve future problems you don&#8217;t have. Most of the time the problems your foresaw will never happen, yet you spent a lot of time preparing for them.</p>
<h2>Test before programming</h2>
<p>Write tests for small parts of your software, they will be very modular, and you will get a trust-able software, and I can assure you that you will be 100% able to embrace the changes.</p>
<h2>Release fully functional versions, with simple features</h2>
<p>As human beings, we want to embrace all possibilities and solve all possible problems at once.</p>
<p>But this is not agile at all. Talk to your client, be pragmatic, he will like to listen the truth: &#8220;You can not ship a full-featured final version of software within the term. But you can totally ship a primary version, fully functional, with all the basic needs of the client. Keep improving the software in next releases&#8221;</p>
<p>I tried to summarize those thoughts, but I need blog posts for each one.</p>
<h1>Applying those thoughts to personal projects</h1>
<p>As I said, I have unfinished projects, and they are still unfinished, mostly because were started with a non-agile approach, and I can&#8217;t get interested to finish them.</p>
<p>But there are a few projects I worked in, and others I am the creator. For instance:</p>
<ul>
<li>Dead Parrot, a pythonic RESTFul framework django-based. Is on release 0.1-hellopolly, being used within some globo.com projects.</li>
<li>Ma-Chérie, a simple filesystem-based web application to navigate through pictures. Current release: 0.1</li>
<li>Sponge, a tiny web framework built on top of CherryPy and used Genshi as default template language. Sponge is the base of Ma-Chérie. Current release: 0.1</li>
<li>Pyccuracy, s BDD acceptance testing tool. <a href="http://tinyurl.com/heynemann">Heynemann</a> started that project, as a comitter, I worked in the biggest refactoring. Current release 1.0.3-viagra</li>
<li>Sleepy, is a crude, slow and rough template language, 100% based in regular expressions (which mades sleepy so slow). Actually I do not plan release it by now,  I am just having some proofs of concept of how possible is to write a template language 100% regex based, just with TDD.</li>
</ul>
<p>All projects above, except Sleepy, were released as well, all them were developed with TDD and have  a good code coverage.</p>
<p>But the big deal is that, actually they will never get finished, for a simple reason. They will be in continuous development and continuous released as well.</p>
<p>By the way, if you want to contribute, just go to <a href="https://github.com/gabrielfalcao">my github</a> profile and check them out.</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2009/07/05/new-projects-agile-releases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hosting and deploying django apps on Dreamhost</title>
		<link>http://gabrielfalcao.com/2008/12/02/hosting-and-deploying-django-apps-on-dreamhost/</link>
		<comments>http://gabrielfalcao.com/2008/12/02/hosting-and-deploying-django-apps-on-dreamhost/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 12:12:00 +0000</pubDate>
		<dc:creator>gabriel</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web development]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=10</guid>
		<description><![CDATA[About two years ago, I&#8217;ve signed up to Dreamhost. My goals were and still being to host my personal projects, websites and so on.
Once I am a Django web developer, one of my first actions were to create a django deployment setup, good and flexible enough. The time passed on and have been got new [...]]]></description>
			<content:encoded><![CDATA[<p>About two years ago, I&#8217;ve signed up to Dreamhost. My goals were and still being to host my personal projects, websites and so on.</p>
<p>Once I am a <a href="http://www.djangoproject.com/">Django</a> web developer, one of my first actions were to create a django deployment setup, good and flexible enough. The time passed on and have been got new experiences, and the best desision, i think, was to create a new python sandbox, i mean, a customized python environment.</p>
<h2>How is it possible ?</h2>
<p>Simple! Just compiling python from scratch, with a fake root path (a prefix)</p>
<p>Anyway, the deployment process involves more variables, like setting both htaccess and dispatch files for each project, installing some basic modules such <a href="http://www.pythonware.com/products/pil/">PIL</a> and <a href="http://sourceforge.net/projects/mysql-python/">MySQL</a> and so on&#8230;</p>
<p>So, i ever wanted to create a super duper script to do all that &#8220;dirty&#8221; work. And i did it last weekend!</p>
<p>I were working ia a freelance job and decided to create a subdomain to host test instance of them.</p>
<p>A new sandbox, ready to make my tests to create the super script.</p>
<p>So folks, i present you the brand new: <strong>django_dreamhost.sh</strong> <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>It&#8217;s composed by 4 files:</p>
<ul>
<li><strong>django_dreamhost.sh</strong> itself</li>
<li><strong>djangify.template</strong> &#8211; a template with will become a script to setup new projects (htaccess and dipatch files, for instance)</li>
<li><strong>htaccess.template</strong> &#8211; a template that will become the .htaccess of each project of yours</li>
<li><strong>dispatch.template</strong> &#8211; will become the dispatch.fcgi for your projects as well</li>
</ul>
<p>&#8220;But do i need to download all them ?&#8221;, of course NO!</p>
<p>You just download the main script, and he will do all do hard work!</p>
<p>&#8220;I wanna contribute, modify or do anything with that script, can I ?&#8221;, of course yes! All parts of the script are GPLv2 +</p>
<p>You can also always get the development version through <a href="http://git.or.cz/">git</a> repository:</p>
<p><strong>git clone http://git.nacaolivre.org/django_dreamhost</strong></p>
<p>Don&#8217;t want to get all code, just the script ?</p>
<p>Download it at: <a href="http://gnu.gabrielfalcao.com/django_dreamhost/django_dreamhost.sh"><strong>http://gnu.gabrielfalcao.com/django_dreamhost/django_dreamhost.sh</strong></a></p>
<h2><strong>What does that script do ?</strong></h2>
<p>He will do the following steps:</p>
<ol>
<li>Download Python, Django, Python-setuptools, Python-fastcgi to a directory called downloads</li>
<li>Extract all</li>
<li>Create a local root at $HOME/.myroot and the subdirs etc and usr</li>
<li>Set the new bin path to you global path through bashrc and bash_profile</li>
<li>Compile and install python to the new prefix: $HOME/.myroot/usr</li>
<li>Install Django, rename django-admin.py to django-admin</li>
<li>Setup your bash-completion to support django scripts</li>
<li>Install the python modules above with the new python</li>
<li>Install PIL and MYSQL modules through easy_install (setuptools)</li>
<li>Download the template scripts to $HOME/projects/script_templates</li>
<li>Replace the custom tags in templates</li>
<li>Move the djangify.template to the new bin PATH: $HOME/usr/bin and give it execution permission</li>
</ol>
<p>I thinks it&#8217;s all.</p>
<p>I currently use <a href="http://www.nongnu.org/fab/">Fabric</a> to help on deployment, and i have a quite smart basic setup for it to work with this dreamhost django environment, but it will be approached in the next blog post <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>See you, folks!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2008/12/02/hosting-and-deploying-django-apps-on-dreamhost/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
