<?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; Gabriel Falcão</title>
	<atom:link href="http://gabrielfalcao.com/author/admin/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>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[agile]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web development]]></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 [...]]]></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<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; 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; 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; <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 <span style="color: #66cc66;">=</span> NameJoiner<span style="color: black;">&#40;</span><br />
&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; 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; <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 />
<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; <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; <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>(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>6</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[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>
		<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[agile]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></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;, [...]]]></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 <span style="color: #66cc66;">=</span> couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak<span style="color: #66cc66;">=</span><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: #66cc66;">,</span> <span style="color: #483d8b;">&quot;awful&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;normal&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;nice&quot;</span><span style="color: #66cc66;">,</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<span style="color: #66cc66;">,</span> replace<span style="color: #66cc66;">=</span><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 <span style="color: #66cc66;">=</span> couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak<span style="color: #66cc66;">=</span><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 <span style="color: #66cc66;">=</span> couleur.<span style="color: black;">Shell</span><span style="color: black;">&#40;</span>linebreak<span style="color: #66cc66;">=</span><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> % x<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; replace<span style="color: #66cc66;">=</span><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"><span style="color: #666666;">user@machine:~$ </span><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>Avoid python pitfalls and be happy</title>
		<link>http://gabrielfalcao.com/2010/01/21/avoid-python-pitfalls-and-be-happy/</link>
		<comments>http://gabrielfalcao.com/2010/01/21/avoid-python-pitfalls-and-be-happy/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 10:59:43 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=148</guid>
		<description><![CDATA[This morning I was just reading the feed, when I stumbled on this post about one of the weird behaviors of lists in Python. In a few words, lists and dictionaries behave like C pointers, thus they are mutable objects. So, if you are beginning on python, you probably will like those articles: 10 python [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I was just reading the feed, when I stumbled on <a href="http://programandosemcafeina.blogspot.com/2010/01/diferencas-entre-ruby-e-python-que.html">this post</a> about one of the weird behaviors of lists in Python.</p>
<p>In a few words, lists and dictionaries behave like C pointers, thus they are mutable objects.</p>
<p>So, if you are beginning on python, you probably will like those articles:</p>
<ul>
<li> <a href="http://zephyrfalcon.org/labs/python_pitfalls.html">10 python pitfalls, what to not to do in python</a></li>
<li><a href="http://www.ferg.org/projects/python_gotchas.html">Python gotchas</a><a href="http://www.ferg.org/projects/python_gotchas.html">, caveats you must know</a></li>
</ul>
<p>Hope it helps <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/01/21/avoid-python-pitfalls-and-be-happy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solving &#8220;connection refused&#8221; issues on Debian Sid</title>
		<link>http://gabrielfalcao.com/2010/01/05/solving-connection-refused-issues-on-debian-sid/</link>
		<comments>http://gabrielfalcao.com/2010/01/05/solving-connection-refused-issues-on-debian-sid/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 01:43:27 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=143</guid>
		<description><![CDATA[Some weeks ago I started to experiment some network issues on my debian sid: The selenium-remote-control was not running: I could even try to do a: &#8220;telnet localhost 4444&#8243;, it just did not work. My Apache-Solr was not capable to subscribe to apache-activemq When reading the log, I saw: Could not connect to broker URL: [...]]]></description>
			<content:encoded><![CDATA[<p>Some weeks ago I started to experiment some network issues on my debian sid:</p>
<ul>
<li>The selenium-remote-control was not running:</li>
</ul>
<p>I could even try to do a: &#8220;telnet localhost 4444&#8243;, it just did not work.</p>
<ul>
<li>My Apache-Solr was not capable to subscribe to apache-activemq</li>
</ul>
<p>When reading the log, I saw:</p>
<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">Could not connect to broker URL: tcp:<span style="color: #000000; font-weight: bold;">//</span>localhost:<span style="color: #000000;">61616</span>. Reason: java.net.ConnectException: Connection refused<br />
Suddenly I noticed something weird <span style="color: #000000; font-weight: bold;">in</span> my netstat:<br />
<br />
tcp6       <span style="color: #000000;">0</span>      <span style="color: #000000;">0</span> :::<span style="color: #000000;">8983</span>                 :::<span style="color: #000000; font-weight: bold;">*</span>                    LISTEN      <span style="color: #000000;">3865</span><span style="color: #000000; font-weight: bold;">/</span>solr-globocom<br />
tcp6       <span style="color: #000000;">0</span>      <span style="color: #000000;">0</span> :::<span style="color: #000000;">8161</span>                 :::<span style="color: #000000; font-weight: bold;">*</span>                    LISTEN      <span style="color: #000000;">3901</span><span style="color: #000000; font-weight: bold;">/</span>activemq-globo<br />
tcp6       <span style="color: #000000;">0</span>      <span style="color: #000000;">0</span> :::<span style="color: #000000;">61616</span>                :::<span style="color: #000000; font-weight: bold;">*</span>                    LISTEN      <span style="color: #000000;">3901</span><span style="color: #000000; font-weight: bold;">/</span>activemq-globo<br />
tcp6       <span style="color: #000000;">0</span>      <span style="color: #000000;">0</span> 127.0.0.1:<span style="color: #000000;">41879</span>         127.0.0.1:<span style="color: #000000;">61616</span>         ESTABLISHED <span style="color: #000000;">3865</span><span style="color: #000000; font-weight: bold;">/</span>solr-globocom<br />
tcp6       <span style="color: #000000;">0</span>      <span style="color: #000000;">0</span> 127.0.0.1:<span style="color: #000000;">61616</span>         127.0.0.1:<span style="color: #000000;">41879</span>         ESTABLISHED <span style="color: #000000;">3901</span><span style="color: #000000; font-weight: bold;">/</span>activemq-globo</div></div>
<p>Everything is being bound as IPv6&#8230; humm, that doesn&#8217;t have a good smell&#8230;.</p>
<p>Looking for solutions I&#8217;ve found this file:</p>
<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"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sysctl.d<span style="color: #000000; font-weight: bold;">/</span>bindv6only.conf</div></div>
<p>interesting, huh?!?</p>
<p>Openning up that file, I saw a full description of it, then I just needed to change its property from this:</p>
<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">net.ipv6.bindv6only = <span style="color: #000000;">1</span></div></div>
<p>to this:</p>
<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">net.ipv6.bindv6only = <span style="color: #000000;">0</span></div></div>
<p>Well, if you have the same problem, jsut change that, restart your PC, and be happy!</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2010/01/05/solving-connection-refused-issues-on-debian-sid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Sponge, a python web framework aimed on testing</title>
		<link>http://gabrielfalcao.com/2009/09/01/introducing-sponge-a-python-web-framework-aimed-on-testing/</link>
		<comments>http://gabrielfalcao.com/2009/09/01/introducing-sponge-a-python-web-framework-aimed-on-testing/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 02:34:18 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=128</guid>
		<description><![CDATA[Some time ago, a friend of mine created a cherrypy-based continuous integration application, we both work with Django, but we think that its stack is too big for simple web projects, specially when we do not need to access SQL databases. More on Django In adition, I think that Django-powered applications are hard to make [...]]]></description>
			<content:encoded><![CDATA[<p><img style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="Sponge's first app" src="http://gabrielfalcao.com/wp-content/uploads/2009/09/Captura_de_tela-1024x640.png" alt="Sponge first prage" width="402" height="251" /></p>
<p style="text-align: center;">Some time ago, a <a href="http://manicprogrammer.com/cs/blogs/heynemann/">friend of mine</a> created a cherrypy-based <a href="https://github.com/heynemann/skink/tree">continuous integration application</a>, we both work with <a href="www.djangoproject.com/">Django</a>, but we think that its stack is too big for simple web projects, specially when we do not need to access SQL databases.</p>
<h1>More on Django</h1>
<p>In adition, I think that Django-powered applications are hard to make <a href="http://en.wikipedia.org/wiki/Unit_testing">unit tests</a>, mostly related to the fact that models, templates and other django helpers need the DJANGO_SETTINGS_MODULE environment variable set, which turn its tests wired.</p>
<p>We have created a few patterns to make Django projects unit-testable, but it is for another post <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Are you trying to say that Django is not a good framework ?</h2>
<p>Nope! I work with Django, and I just LOVE Django, that is a great framework. Its models, forms, and everything else are awesome, and help me to write web applications without much effort, thus keeping high level of quality.</p>
<h1>So, why did you create another framework ?</h1>
<p>As I&#8217;ve just <a href="http://gabrielfalcao.com/2009/07/05/new-projects-agile-releases/">said some posts ago</a>, I really enjoy agile, and I use to write simple web applications that does not demand the whole Django stack, and I need to have agility to write my tests.</p>
<p>CherryPy is a good solution for me, I don&#8217;t want another huge-ish framework, even if its based on cherrypy. I just need a few helpers functions, and a pattern to follow.</p>
<h2>Idealizing sponge</h2>
<h1><span style="background-color: #ffffff; font-weight: normal; font-size: 13px; ">Bernardo and me wrote a few web applications with cherrypy, and always focusing in TDD, we needed to create some helper classes to cherrypy. Sometime after, we figured out that those helpers could be grouped in a simple library, or a kind of tiny framework.</span></h1>
<p>I started some mashups, and Sponge has been developed.</p>
<p>The name comes from the fact that a sponge can be used to dry stuff. We like the concept of <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>, hence the name <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Sponge has been developed with TDD, but that is not all.</p>
<p>I&#8217;m trying to keep 100% of code coverage in both unit + functional tests, at minimum. It&#8217;s because 100% of coverage does not assure that the code works. Lines of code can be covered with some tests, but the same lines can have one or more different behaviours that won&#8217;t be found with 100% of coverage.</p>
<h1>Principles</h1>
<ul>
<li><span style="background-color: #ffffff; ">Help and incentivate developer to write unit and functional tests</span></li>
<li><span style="background-color: #ffffff;">Less friction as possible</span></li>
<li><span style="background-color: #ffffff;">Be simple to configure</span></li>
<li><span style="background-color: #ffffff;">Be simple to deploy</span></li>
<li><span style="background-color: #ffffff;">Be 100% testable, specially with unit tests</span></li>
<li><span style="background-color: #ffffff;">Provide pretty URLS <a href="http://routes.groovie.org/">through a rails-like</a> syntax</span></li>
<li><span style="background-color: #ffffff;">Be as most compliant as possible, with package-systems, such as <a href="http://pt.wikipedia.org/wiki/Advanced_Packaging_Tool">APT</a></span></li>
<li><span style="background-color: #ffffff;">Free software (LGPL-3)</span></li>
<li><span style="background-color: #ffffff;">Comes with <a href="http://jquery.com/">jQuery</a> javascript library and <a href="http://960.gs/">960 grid system</a></span></li>
<li><span style="background-color: #ffffff;">Fun to use <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></li>
</ul>
<h1>Hands on!</h1>
<h2>Installing</h2>
<p>If you are using Debian Unstable, just run:</p>
<p>sudo aptitude install python-sponge</p>
<p>If not, you will need, unfortunately, to use setuptools:</p>
<p>In this case, just grab the bleeding edge version through git:</p>
<p>git clone git://github.com/gabrielfalcao/sponge.git</p>
<p>Or just the latest stable relase:</p>
<p><a href="http://github.com/gabrielfalcao/sponge/zipball/0.3.1-scooby"><span style="color: #000000;">Sponge 0.3.1</span></a></p>
<p>Extract, if needed, and run:</p>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">sudo python setup.py install</pre>
<h2>Tutorial</h2>
<p>Sponge comes with a simple tutorial within its documentation, but you can <a href="http://gnu.gabrielfalcao.com/projects/sponge/tutorial.html#tutorial">access it online</a></p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2009/09/01/introducing-sponge-a-python-web-framework-aimed-on-testing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Emacs + Snippets</title>
		<link>http://gabrielfalcao.com/2009/08/16/emacs-snippets/</link>
		<comments>http://gabrielfalcao.com/2009/08/16/emacs-snippets/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 02:42:16 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=125</guid>
		<description><![CDATA[People use to joke on me about the fact that I use EMACS, some say that I even need to use my toes to acomplish EMACS commands, and so on&#8230; But I keep being even more productive, and every day I figure out new ways to improve it. I really use EMACS the whole day, [...]]]></description>
			<content:encoded><![CDATA[<p>People use to joke on me about the fact that I use EMACS, some say that I even need to use my toes to acomplish EMACS commands, and so on&#8230;</p>
<p>But I keep being even more productive, and every day I figure out new ways to improve it.</p>
<p>I really use EMACS the whole day, I keep editing anything with this awesome editor.</p>
<p>This weekend I was starting a new project, and as I use to, I was needing to repeat  the same GPL headers at every file.</p>
<p>So I found myself questioning if it could be more productive than inserting rough templates on my files.</p>
<p>Then I found out this <a href="http://code.google.com/p/yasnippet/">yasnippet</a>, which is totally awesome, and made me be even more productive.</p>
<p>For those who also like emacs, I share my <a href="http://github.com/gabrielfalcao/emacs_config/tree">emacs configuration</a> on github.</p>
<p>There is a screencast that I made. Is a EMACS snippet demo.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/d3SRIL4cde0&#038;hl=pt-br&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999&#038;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/d3SRIL4cde0&#038;hl=pt-br&#038;fs=1&#038;color1=0x3a3a3a&#038;color2=0x999999&#038;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2009/08/16/emacs-snippets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bolacha, httplib2 wrapper with cookie handling and file upload.</title>
		<link>http://gabrielfalcao.com/2009/08/09/python-bolacha-httplib2-wrapper-with-cookie-handling-and-file-upload/</link>
		<comments>http://gabrielfalcao.com/2009/08/09/python-bolacha-httplib2-wrapper-with-cookie-handling-and-file-upload/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 04:14:08 +0000</pubDate>
		<dc:creator>Gabriel Falcão</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://gabrielfalcao.com/?p=123</guid>
		<description><![CDATA[I really like httplib2, but unfortunately it does not oficially support sending multipart/form-data. So last Monday I was at work, and realized that I was needing exactly to make a http upload from within a python program, and also needed to make a session login right before. I remember that I needed that before, but [...]]]></description>
			<content:encoded><![CDATA[<p>I really like httplib2, but unfortunately it does not oficially support sending multipart/form-data.</p>
<p>So last Monday I was at work, and realized that I was needing exactly to make a http upload from within a python program, and also needed to make a session login right before.</p>
<p>I remember that I needed that before, but I could not find something simple and concise, yet pythonic and well tested.</p>
<p>So I decided to work on a proof of concept, 2 days after that, at last wednesday, I got really sick. I thought was just a simple flu, but I got even worst. Going to hospital, doctors found out I have sinusitis.</p>
<p>So since wednesday I am at home, having lots of damn medicines.</p>
<p>But the good thing is that I got time enough to hack <img src='http://gabrielfalcao.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So I would like to introduce you Bolacha.</p>
<p>You can see de docs <a href="http://gnu.gabrielfalcao.com/bolacha/">here</a></p>
<p>There is a debian package available <a href="http://deb.gabrielfalcao.com/unstable/python-bolacha_0.2_all.deb">here</a></p>
<p>The code is available at my github page: http://github.com/gabrielfalcao/bolacha/tree/master</p>
]]></content:encoded>
			<wfw:commentRss>http://gabrielfalcao.com/2009/08/09/python-bolacha-httplib2-wrapper-with-cookie-handling-and-file-upload/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[agile]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></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 [...]]]></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>
	</channel>
</rss>

