<?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>Keep Learning &#187; Rails</title>
	<atom:link href="http://www.makemesimple.com/blog/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.makemesimple.com/blog</link>
	<description>Conhecimento nunca é o bastante</description>
	<lastBuildDate>Sat, 21 Aug 2010 16:41:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Utilizando rack-debug para debugging com Passenger</title>
		<link>http://www.makemesimple.com/blog/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/</link>
		<comments>http://www.makemesimple.com/blog/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 20:06:27 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=294</guid>
		<description><![CDATA[Desenvolver aplicações Rails utilizando o Phusion Passenger (principalmente no Mac OS X com o Passenger preference pane) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem ruby-debug quando precisava de breakpoints para debuggar o código. Uma maneira de conseguir isso é através da gem/plugin rack-debug. Para utilizá-la, [...]]]></description>
			<content:encoded><![CDATA[<p>Desenvolver aplicações Rails utilizando o <a target="_blank" href="http://www.modrails.com/">Phusion Passenger</a> (principalmente no Mac OS X com o <a target="_blank" href="http://www.fngtps.com/passenger-preference-pane">Passenger preference pane</a>) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem <a target="_blank" href="http://rubyforge.org/projects/ruby-debug/">ruby-debug</a> quando precisava de breakpoints para <em>debuggar</em> o código.</p>
<p>Uma maneira de conseguir isso é através da gem/plugin <a target="_blank" href="http://github.com/ddollar/rack-debug/tree/master">rack-debug</a>. Para utilizá-la, segui os passos abaixo.</p>
<p>1. Instalação</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> $ script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>ddollar<span style="color: #000000; font-weight: bold;">/</span>rack-debug.git
&nbsp;
 <span style="color: #666666; font-style: italic;"># config/environments/development.rb</span>
 config.middleware.use <span style="color: #ff0000;">&quot;Rack::Debug&quot;</span></pre></div></div>

<p>2. Chamar o debugger onde necessário:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@status</span> = current_user.<span style="color:#9900CC;">statuses</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:status</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    debugger
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@status</span>.<span style="color:#9900CC;">valid</span>?
...</pre></div></div>

<p>3. Conectar-se ao debugger</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> <span style="color: #666666; font-style: italic;"># No diretório da aplicação, chamar a task rake</span>
 $ rake debug
 Connected.</pre></div></div>

<p>4. Ao executar a linha onde o debugger foi chamado, a aplicação para e você tem acesso ao console do debugger</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> <span style="color:#006600; font-weight:bold;">&#40;</span>rdb:<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#0066ff; font-weight:bold;">@status</span>
 <span style="color:#008000; font-style:italic;">#&lt;Status id: 231, text: &quot;Testing rack-debug&quot;, user_id: 4, ...&gt;</span></pre></div></div>

<p>Pronto. Happy debugging! <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong>: ao chamar a task rake, pode ocorrer um erro com a mensagem &#8220;Server is not running or Passenger has spooled down&#8221;. Neste caso, reinicie o Apache e tudo deve funcionar normalmente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testes envolvendo tempo: usando a gem time-warp</title>
		<link>http://www.makemesimple.com/blog/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/</link>
		<comments>http://www.makemesimple.com/blog/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 16:46:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=269</guid>
		<description><![CDATA[É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo. Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: [...]]]></description>
			<content:encoded><![CDATA[<p>É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo.</p>
<p>Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: &#8220;<a target="_blank" href="http://www.infoq.com/news/2008/08/Mock-Roles-Pryce-and-Freeman">Não use fakes em objetos que não são seus</a>&#8220;. Na maioria do tempo isso pode não causar problemas, mas alterar o comportamento de uma classe usada internamente pela linguagem não soa bem e pode causar bugs difíceis de rastrear.</p>
<p>Aí entra a gem <a target="_blank" href="http://github.com/iridesco/time-warp/tree/master">time-warp</a>. Ela ainda trabalha sobre as classes do Ruby, mas provê uma camada específica para testes para todo código executado em um bloco definido pelo programador. Um exemplo de uso (da <a target="_blank" href="http://twtapp.info/">nossa aplicação feita para o Rails Rumble</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">&quot;should only silence tweets with the desired word inside the configured time interval&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  pretend_now_is<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">utc</span>.<span style="color:#9900CC;">beginning_of_day</span> <span style="color:#006600; font-weight:bold;">+</span> 1.<span style="color:#9900CC;">hour</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    tweet1.<span style="color:#9900CC;">sent_at</span> = 2.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">ago</span>
    tweet2.<span style="color:#9900CC;">sent_at</span> = 32.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</span>
    tweet3.<span style="color:#9900CC;">sent_at</span> = 1.<span style="color:#9900CC;">hour</span>.<span style="color:#9900CC;">from_now</span>
&nbsp;
    collection = <span style="color:#006600; font-weight:bold;">&#91;</span>tweet1, tweet2, tweet3<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    Silencer.<span style="color:#9900CC;">apply</span><span style="color:#006600; font-weight:bold;">&#40;</span>collection, <span style="color:#006600; font-weight:bold;">&#123;</span>:word <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;soccer&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:until</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> 30.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  tweet1.<span style="color:#9900CC;">should</span> be_filtered
  tweet2.<span style="color:#9900CC;">should</span> be_filtered
  tweet3.<span style="color:#9900CC;">should_not</span> be_filtered
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>A gem adiciona o método &#8220;pretend_now_is&#8221;, que recebe um parâmetro com o horário desejado e um bloco. Dentro desse bloco, todo código executado é &#8220;transportado no tempo&#8221; para o horário definido. Além de tornar a manipulação das classes de tempo mais segura, o código fica muito mais elegante.</p>
<p>Veja mais detalhes no <a target="_blank" href="http://github.com/iridesco/time-warp/blob/884623fec90687c7f3c28b8e8074a39c96946cbb/README.md">README da gem</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides e notas da minha sessão no FISL10</title>
		<link>http://www.makemesimple.com/blog/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/</link>
		<comments>http://www.makemesimple.com/blog/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 16:52:25 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=228</guid>
		<description><![CDATA[Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;. Download. Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo.]]></description>
			<content:encoded><![CDATA[<p>Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;.</p>
<p><a href="http://makemesimple.com/files/fisl10.pdf" target="_blank">Download</a>.</p>
<p>Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Ruby Quick Tip: Aprendendo através de testes</title>
		<link>http://www.makemesimple.com/blog/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/</link>
		<comments>http://www.makemesimple.com/blog/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 21:07:09 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=156</guid>
		<description><![CDATA[Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes. Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura. Se você usa o TextMate, é muito fácil criar um caso [...]]]></description>
			<content:encoded><![CDATA[<p>Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes. </p>
<p>Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura.</p>
<p>Se você usa o TextMate, é muito fácil criar um caso de testes. Basta abrir uma janela do editor, ativar o bundle do Ruby, digitar <em>tc</em> e pressionar a tecla <em>tab</em>:</p>
<p><img src="http://www.makemesimple.com/blog/wp-content/uploads/2009/02/ishot-1.jpg" alt="TextMate" title="TextMate" width="475" height="449" class="aligncenter size-full wp-image-161" /></p>
<p><img src="http://www.makemesimple.com/blog/wp-content/uploads/2009/02/ishot-2.jpg" alt="test case scaffold" title="test case scaffold" width="475" height="449" class="aligncenter size-full wp-image-162" /></p>
<p>Com isso temos um &#8220;esqueleto&#8221; de um caso de testes pronto. Pressionando tab, o foco do cursor passa por pontos importantes, como o require da biblioteca a ser testada, o nome do caso de testes etc. Agora, basta modificar de acordo com o que queremos testar e, através do atalho command+R, executar os testes e verificar o resultado:</p>
<p><img src="http://www.makemesimple.com/blog/wp-content/uploads/2009/02/ishot-3.jpg" alt="test" title="test" width="475" height="449" class="aligncenter size-full wp-image-163" /></p>
<p><img src="http://www.makemesimple.com/blog/wp-content/uploads/2009/02/ishot-41.jpg" alt="ishot-41" title="ishot-41" width="500" height="331" class="aligncenter size-full wp-image-174" /></p>
<p><strong>Veja também</strong>:</p>
<p><a href="http://www.makemesimple.com/blog/2007/08/27/aprendizado-orientado-por-testes/">Aprendizado orientado por testes</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seu framework não faz BDD</title>
		<link>http://www.makemesimple.com/blog/2009/01/08/seu-framework-nao-faz-bdd/</link>
		<comments>http://www.makemesimple.com/blog/2009/01/08/seu-framework-nao-faz-bdd/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 03:49:51 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=142</guid>
		<description><![CDATA[Eu sinto uma &#8220;pontada&#8221; no cérebro quando ouço ou leio coisas como &#8220;o RSpec (ou Shoulda, test/spec etc) é um framework BDD&#8221;. Não existe algo como um &#8220;framework BDD&#8221;. Tenha em mente que quem pratica ou não o BDD é o desenvolvedor. O que existe são frameworks ou bibliotecas que adicionam uma boa dose de [...]]]></description>
			<content:encoded><![CDATA[<p>Eu sinto uma &#8220;pontada&#8221; no cérebro quando ouço ou leio coisas como &#8220;o RSpec (ou Shoulda, test/spec etc) é um framework BDD&#8221;.</p>
<p>Não existe algo como um &#8220;framework BDD&#8221;. Tenha em mente que quem pratica ou não o BDD é o desenvolvedor. O que existe são frameworks ou bibliotecas que adicionam uma boa dose de açúcar sintático para facilitar o estilo de escrita para quem deseja praticar essa técnica de testes.</p>
<p>Os <a href="http://dannorth.net/introducing-bdd" target="_blank">maiores</a> <a href="http://blog.daveastels.com/files/BDD_Intro.pdf" target="_blank">proponentes</a> do BDD enfatizam que a maior mudança em relação às técnicas tradicionais é mesmo a sintaxe. Porém, isso não quer dizer que basta utilizar uma sintaxe &#8220;mais legível&#8221; (o que é discutível também) para pular no vagão do BDD. A sintaxe bonitinha é um auxílio, uma ferramenta com o objetivo de diminuir as dificuldades na transição de um <strong>modo de pensar</strong>, que é onde a verdadeira diferença reside. Muitas dessas dificuldades são, inclusive, ditas de origem &#8220;psicológica&#8221;, como a abolição da palavra &#8220;test&#8221; nos nomes dos métodos para forçar o pensamento no sentido de uma verificação de comportamento ao invés de um teste de estado (medida defendida através da <a href="http://pt.wikipedia.org/wiki/Hip%C3%B3tese_de_Sapir-Whorf" target="_blank">hipótese de Sapir-Whorf</a>).</p>
<p>De fato, posso afirmar que a maior parte das suítes de testes escritas em RSpec, Shoulda ou test/spec que já tive a oportunidade de examinar (seja trabalhando, seja &#8220;navegando&#8221; por projetos open source &#8211; uma grande fonte de aprendizado), falha miseravelmente na tentativa de adotar o BDD, tropeçando feio em erros como verificar estado ao invés de comportamento, testar funcionalidades da linguagem ou framework e, principalmente, overmocking &#8211; chegando ao ponto em que um teste não verifica mais nada, apenas mocks e stubs &#8211; o que nos leva a testes quebradiços ou testes que não falham mesmo que você apague o código que eles deveriam verificar.</p>
<p>Esse último item leva a um outro ponto importante (e, aqui, uma visão muito pessoal &#8211; acredito ser compartilhada por poucos): acredita-se que o uso de mocks configura o uso do BDD, pois estabelecer expectativas em relação à interfaces e, consequentemente, isolar horizontalmente os componentes testados, passa a ser, &#8220;automaticamente&#8221;, verificação de comportamento. O uso de mocks não estabelece nada além de uma expectativa de interação &#8211; uma interface. </p>
<p>Como um <a href="http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting" target="_blank">classicista</a> evito o uso de mocks (e dublês em geral), reservando-os para onde realmente é difícil ou pouco prático o uso de um objeto real ou, como deveria ser seu principal uso, uma ferramenta de design de código através da qual modelamos interfaces ainda não existentes à medida em que praticamos o TDD (ou seja, escrevemos testes antes da implementação do código real) &#8211; e os substituo assim que a classe real é implementada, quando aplicável.</p>
<p>Então, não acredite que por utilizar alguma ferramenta facilitadora, você, instantâneamente, estará praticando BDD. Estude a técnica e a filosofia envolvida e você poderá utilizá-la com qualquer ferramenta para testes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/01/08/seu-framework-nao-faz-bdd/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jogue fora os testes quebradiços</title>
		<link>http://www.makemesimple.com/blog/2008/10/24/jogue-fora-os-testes-quebradicos/</link>
		<comments>http://www.makemesimple.com/blog/2008/10/24/jogue-fora-os-testes-quebradicos/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 17:23:03 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=141</guid>
		<description><![CDATA[É isso mesmo! Jogue fora. Todos eles! Você não precisa de deles. Você precisa de testes que garantam o comportamento do seu sistema. Software não é sobre o código escrito, software é sobre gerar o comportamento esperado a partir de um conjunto de requerimentos. Bem, não sou um especialista em testes nem um guru da [...]]]></description>
			<content:encoded><![CDATA[<p>É isso mesmo! Jogue fora. Todos eles! Você não precisa de deles. Você precisa de testes que garantam o comportamento do seu sistema. Software não é sobre o código escrito, software é sobre gerar o comportamento esperado a partir de um conjunto de requerimentos.</p>
<p>Bem, não sou um especialista em testes nem um guru da programação, mas tenho algumas opiniões. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong style="font-size: 15px;">O que é um teste quebradiço (ou &#8220;brittle test&#8221;)?</strong></p>
<p>Um teste quebradiço é aquele que passa a falhar após uma alteração em código não relacionado ao que ele deveria testar ou quando o código que ele testa é alterado, mas o comportamento do sistema não muda.</p>
<p>Além do custo de manutenção inerente à correção de testes que quebram &#8220;sem motivo&#8221;, ocorre também um impacto na moral e na motivação dos desenvolvedores. Se um desenvolvedor faz mudanças em um código e, ao integrá-lo, testes começam a falhar por motivos como inconsistência de dados em banco ou alto acoplamento, é praticamente certo que isso irá irritá-lo e, a médio prazo, fazer com que ele abandone os testes, criando verdadeiros &#8220;ferros-velhos&#8221; de testes sucateados. As quebras se tornarão cada vez mais frequentes e, logo, processos como integração contínua serão completamente abandonados.</p>
<p><strong style="font-size: 15px;">Casos comuns</strong></p>
<p><strong>Fixtures</strong></p>
<p>Manter os grafos de objetos através de fixtures torna-se exponencialmente mais complexo à medida que sua aplicação aumenta de tamanho e cria mais relacionamentos entre os objetos. Adicione um atributo ou relacionamento entre modelos e um grande número de testes automaticamente começará a quebrar, exigindo esforço considerável para correção.</p>
<p>Utilize algo como object_daddy e factory_girl que, sim, também precisarão de alguma manutenção após alterações na estrutura de dados, mas exigindo esforço muito menor.</p>
<p><strong>Testes de views em código</strong> (usando coisas como assert_tag ou o matcher have_tag)</p>
<p>Esses testes são uma completa e desnecessária perda de tempo. Uma mudança em alguma classe ou nome de campo e, bang!, testes quebrando sem que o comportamento da aplicação tenha sido afetado.</p>
<p>Você pode ser moderado nesses testes e não torná-los muito específicos para evitar isso mas, nesse caso, use algo como o Selenium, também com cuidado, pois é possível cair no mesmo erro com essa ferramenta.</p>
<p>Teste o que influi no comportamento, como o fluxo de redirecionamentos ou elementos com ids utilizados para chamadas ajax.</p>
<p>O Selenium também tem a vantagem de poder ser utilizado por testadores com algum conhecimento de estrutura Html.</p>
<p><strong>Abuso de mocks e stubs</strong></p>
<p>Isto é, para mim, um dos grandes vilões dos testes quebradiços. Esse abuso leva os testes a ficarem altamente acoplados a detalhes de implementação. Por exemplo (o exemplo é bobo, apenas para ilustrar):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Delivery
  <span style="color:#9966CC; font-weight:bold;">def</span> has_packages?
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">packages</span>.<span style="color:#9900CC;">count</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> DeliveryTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span>
  context <span style="color:#996600;">&quot;A scheduled delivery&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    setup <span style="color:#9966CC; font-weight:bold;">do</span>
      Delivery.<span style="color:#9900CC;">stubs</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:count</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">returns</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@delivery</span> = Delivery.<span style="color:#9900CC;">new</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    should <span style="color:#996600;">&quot;have packages&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      assert <span style="color:#0066ff; font-weight:bold;">@delivery</span>.<span style="color:#9900CC;">has_packages</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Se, por um motivo qualquer, a implementação do método <em>has_packages?</em> mudar e passar a utilizar, por exemplo, o método <em>size</em> ao invés de <em>count</em>, o teste passará a quebrar sem que o comportamento tenha sido alterado. O exemplo é simples mas, em casos reais, isso é um grande problema. <del datetime="2009-02-05T03:37:15+00:00">Note que stubs tendem a deixar os testes mais acoplados do que mocks.</del></p>
<p>Algumas soluções pra isso são: não utilizar mocks e stubs (o que é um tanto extremista), aumentar o encapsulamento das classes ou aceitar isso e continuar.</p>
<p>Esse tipo de coisa costuma acontecer quando queremos utilizar mocks e stubs para tornarmos os testes independentes de recursos externos, como banco de dados. Nesses casos, o trade-off entre acoplamento do teste ao código e o ganho em velocidade de execução ou tempo de manutenção através do isolamento deve ser avaliado.</p>
<p><strong style="font-size: 15px;">Guias gerais</strong></p>
<p>Para evitar testes quebradiços, algumas guias podem ser utilizadas para a maioria dos casos:</p>
<ul>
<li>Especifique apenas o que você quer que aconteça e nada mais</li>
<li>Em termos de mocks e stubs: use stubs para queries (tudo o que retorna dados e não modifica estado) e mocks para comandos (que não necessariamente retornam algo, mas modificam estado)</li>
<li>Lembre-se de que o que importa é o comportamento do método/classe/sistema. Como isto é implementado, em nível de código, não deve fazer diferença nos seus testes</li>
</ul>
<p>Como já disse, não sou um especialista. Então, se você percebeu alguma grande besteira nesse post, não exite em discutir, eu tenho a mente aberta. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong></p>
<p>Note que mocks e stubs, quando usados corretamente, são uma importante ferramenta de design. Esse tipo de ferramenta, além de isolar os testes de recursos externos, tem o intuito (e talvez até o principal objetivo) de servir como apoio à prática do TDD: enquanto escreve os testes antes do código, mocks e stubs (e dublês em geral) permitem que você especifique o comportamento de partes ainda não existentes da aplicação. Nesse processo, torna-se mais fácil detectar falhas como alto acoplamento e corrigí-las o quanto antes, gerando menos stress.</p>
<p>Leia mais:</p>
<ul>
<li><a href="http://szeryf.wordpress.com/2008/01/07/does-stubbing-make-your-tests-brittle/" target="_blank">Does stubbing make your tests brittle?</a></li>
<li><a href="http://evang.eli.st/blog/2008/2/4/sorry-you-re-just-not-my-type" target="_blank">Sorry, you&#8217;re just not my type</a></li>
<li><a href="http://giantrobots.thoughtbot.com/2007/9/6/brittle-tests" target="_blank">Brittle tests</a></li>
<li><a href="http://www.martinfowler.com/articles/mocksArentStubs.html" target="_blank">Mocks aren&#8217;t stubs</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/10/24/jogue-fora-os-testes-quebradicos/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Matchers vs Assertions: DSLs não são linguagens naturais</title>
		<link>http://www.makemesimple.com/blog/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/</link>
		<comments>http://www.makemesimple.com/blog/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 03:15:54 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=139</guid>
		<description><![CDATA[Ok, todo o tempo eu escuto o mesmo argumento quando alguém fala do RSpec (o mesmo foi usado por Jay Fields em sua palestra no Rails Summit, semana passada): Matchers são superiores à asserções porque, quando estou conversando com alguém, eu não afirmo &#8220;Ei, assira que são iguais: 2, 1+1&#8243;, eu afirmo &#8220;Ei, 1+1 deve [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, todo o tempo eu escuto o mesmo argumento quando alguém fala do RSpec (o mesmo foi usado por Jay Fields em sua palestra no Rails Summit, semana passada):</p>
<blockquote><p>Matchers são superiores à asserções porque, quando estou conversando com alguém, eu não afirmo &#8220;Ei, assira que são iguais: 2, 1+1&#8243;, eu afirmo &#8220;Ei, 1+1 deve ser igual a 2&#8243;.</p></blockquote>
<p><strong>Bullshit!</strong></p>
<p style="text-align: center"><img class="aligncenter size-medium wp-image-140" title="Bullshit" src="http://www.makemesimple.com/blog/wp-content/uploads/2008/10/originals_bullshit1_ranndino-225x300.jpg" alt="Absolute Bullshit!" width="225" height="300" /></p>
<p>Trata-se de uma falácia (<strong><em>Dicto Simpliciter</em></strong>) e bem frágil. O que é óbvio e passa despercebido nesse caso é que Linguagens Específicas de Domínio (Domain Specific Languages, DSLs) não são linguagens naturais. Uh-oh! <strong>Tão</strong> óbvio.</p>
<p>Você com certeza fica completamente perdido nas discussões médicas do seriado House. Tente conversar com um engenheiro elétrico sobre o processo de geração de energia elétrica numa usina nuclear. <strong>Tente</strong> entender 20% do que ele fala.</p>
<p>Linguagens específicas de domínio são utilizadas por <strong>especialistas</strong> no domínio em questão. Então me diga se, dentro de um teste, não está o pragmático desenvolvedor em um domínio <strong>muito específico</strong> onde, sim, asserções fazem todo o sentido. Nem sequer tente argumentar que especificações (que substituem os malfadados testes do TDD) são feitos para que clientes entendam. Don&#8217;t fool yourself.</p>
<p>Matchers <strong>não</strong> são ruins, não me entenda mal. São, sim, muito legais e <strong>legíveis</strong>. Mas dizer que asserções &#8220;não são naturais&#8221; e tentar fazer disso um ponto de superioridade é falta de conhecimento.</p>
<p><strong>Observações</strong>: sim, eu prefiro o Shoulda ao RSpec e não vejo problema nenhum na utilização de nenhum dos dois. O ponto aqui é lembrar que DSLs não são inglês ou português, são linguagens muito específicas em um dado contexto. O exemplo citado foi o que me veio à cabeça mais rapidamente, talvez devido ao Rails Summit e à palestra de Jay Fields.</p>
<p>Leia mais:</p>
<p><a href="http://pragdave.blogs.pragprog.com/pragdave/2008/03/the-language-in.html" target="_blank">The &#8216;Language&#8217; in Domain-Specific Language Doesn&#8217;t Mean English (or French, or Japanese, or &#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Edit in place restful com Rails 2.1</title>
		<link>http://www.makemesimple.com/blog/2008/09/03/edit-in-place-restful-com-rails-21/</link>
		<comments>http://www.makemesimple.com/blog/2008/09/03/edit-in-place-restful-com-rails-21/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 03:37:59 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=137</guid>
		<description><![CDATA[A funcionalidade &#8220;edit in place&#8221; é aquela na qual, ao clicar em um texto na página web, disponibiliza-se um campo para edição do texto clicado. Nas versões &#8220;não-Rest&#8221; do Rails, era comum o uso do plugin in_place_editing para conseguir essa funcionalidade. Para as versões mais novas, ainda é possível utilizar esse plugin, mas a solução [...]]]></description>
			<content:encoded><![CDATA[<p>A funcionalidade &#8220;edit in place&#8221; é aquela na qual, ao clicar em um texto na página web, disponibiliza-se um campo para edição do texto clicado.</p>
<p>Nas versões &#8220;não-Rest&#8221; do Rails, era comum o uso do plugin in_place_editing para conseguir essa funcionalidade. Para as versões mais novas, ainda é possível utilizar esse plugin, mas a solução acaba ficando bem grosseira. Pesquisando sobre isso, encontrei o plugin <a href="http://github.com/nakajima/better-edit-in-place/tree/master" target="_blank">better-edit-in-place</a>, que permite utilizar a interface Rest padrão do Rails para conseguir a funcionalidade.</p>
<p>Depois de instalar o plugin, você precisa de apenas três passos para fazer tudo funcionar:</p>
<p>1. Escrever/incrementar os testes funcionais do controller (test first, aqui com Shoulda e&#8230; ahn&#8230; fixtures&#8230;):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">context <span style="color:#996600;">&quot;on Ajax PUT to :update&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  setup <span style="color:#9966CC; font-weight:bold;">do</span>
    xhr <span style="color:#ff3333; font-weight:bold;">:put</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> emails<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:address <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'new_email@email.com'</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  should_assign_to <span style="color:#ff3333; font-weight:bold;">:email</span>
  should_respond_with <span style="color:#ff3333; font-weight:bold;">:success</span>
  should_not_set_the_flash
&nbsp;
  should <span style="color:#996600;">&quot;update the email address&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    assert_equal assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:email</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">address</span>, <span style="color:#996600;">'new_email@email.com'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>2. Criar uma ação update no controller do recurso ou adicionar o formato correto ao bloco respond_to:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> update
  <span style="color:#0066ff; font-weight:bold;">@email</span> = Email.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0066ff; font-weight:bold;">@email</span>.<span style="color:#9900CC;">update_attribute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:address</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:email</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:address</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:json</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@email</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#008000; font-style:italic;">#voce que sabe...</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>3. Ajustar seu markup para que a parte JavaScript do plugin funcione. Para isso, basta utilizar um helper disponibilizado pelo plugin:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span>= edit_in_place<span style="color:#006600; font-weight:bold;">&#40;</span>email, <span style="color:#ff3333; font-weight:bold;">:address</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>Pronto. Ao abrir a página e clicar sobre o elemento <em>span</em> que exibe o texto do atributo passado ao helper, o mesmo será substituído por uma caixa de texto com um botão para salvar e um link para cancelar a ação. Tudo simples e de forma muito mais limpa. O plugin também funciona com recursos aninhados.</p>
<p><strong>Obs:</strong> note que ignorei &#8220;detalhes&#8221; como validação do modelo, entre outros importantes. Fiz isso apenas pra encurtar o post, não faça o mesmo em aplicações reais. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/09/03/edit-in-place-restful-com-rails-21/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Um pouco mais sobre named_scopes</title>
		<link>http://www.makemesimple.com/blog/2008/07/30/um-pouco-mais-sobre-named_scopes/</link>
		<comments>http://www.makemesimple.com/blog/2008/07/30/um-pouco-mais-sobre-named_scopes/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 03:23:13 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=135</guid>
		<description><![CDATA[Um pouco mais? Mas cadê o primeiro artigo sobre isso? Bom, não o escrevi, mas vou partir do ponto em que parou o Nando Vieira em seu artigo sobre named_scopes. Logo, assumo que você já sabe o que é um named_scope e conhece algumas possibilidades, como condições dinâmicas e encadeamento de named_scopes. Apenas lendo uma [...]]]></description>
			<content:encoded><![CDATA[<p>Um pouco mais? Mas cadê o primeiro artigo sobre isso? Bom, não o escrevi, mas vou partir do ponto em que parou o <a href="http://simplesideias.com.br/" target="_blank">Nando Vieira</a> em seu <a href="http://simplesideias.com.br/utilizando-o-named_scope-no-activerecord-do-ruby-on-rails-21/" target="_blank">artigo sobre named_scopes</a>. Logo, assumo que você já sabe o que é um named_scope e conhece algumas possibilidades, como condições dinâmicas e encadeamento de named_scopes.</p>
<p>Apenas lendo uma introdução aos named_scopes já dá pra ficar bem empolgado. É um recurso simples e, ao mesmo tempo, poderoso e, quando bem utilizado, pode resulta no código bonito e sucinto que buscamos todo dia.</p>
<p>Vamos, então, explorar mais algumas possibilidades desse recurso.</p>
<p><span id="more-135"></span><br />
<strong>Modificadores para filtros</strong></p>
<p>Além de estabelecer condições de filtro, podemos aplicar modificadores a eles. Um exemplo é aplicando ordenação:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:boys</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;gender = ?&quot;</span>, <span style="color:#996600;">'M'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:girls</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;gender = ?&quot;</span>, <span style="color:#996600;">'F'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:created_since</span>, <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>days<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:conditions <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;created_at &gt;= ?&quot;</span>, days<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
 <span style="color:#008000; font-style:italic;">#modificando o filtro com ordenação</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:by_first_name</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;first_name ASC&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Isso possibilita os seguintes usos:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">girls</span>.<span style="color:#9900CC;">by_first_name</span>
User.<span style="color:#9900CC;">boys</span>.<span style="color:#9900CC;">by_first_name</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#ou, somente:</span>
User.<span style="color:#9900CC;">by_first_name</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#encadeando como se não houvesse amanhã e operando sobre o resultado!</span>
User.<span style="color:#9900CC;">girls</span>.<span style="color:#9900CC;">created_since</span><span style="color:#006600; font-weight:bold;">&#40;</span>5.<span style="color:#9900CC;">days</span>.<span style="color:#9900CC;">ago</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_first_name</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>:first_name<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><strong>Flexibilizando os escopos</strong></p>
<p>Que tal um filtro aplicável a diferentes atributos do modelo? Vamos lá:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#adding the scope to ActiveRecord::Base so it's available to all models</span>
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:contains</span>, <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>column, text<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:conditions <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;lower(#{column}) LIKE ?&quot;</span>, <span style="color:#996600;">&quot;%#{text.downcase}%&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Utilizando:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">contains</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span>, <span style="color:#996600;">&quot;%mat%&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
User.<span style="color:#9900CC;">contains</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:last_name</span>, <span style="color:#996600;">&quot;Sinclair&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#encadeando...</span>
User.<span style="color:#9900CC;">boys</span>.<span style="color:#9900CC;">contains</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:last_name</span>, <span style="color:#996600;">&quot;S%&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_first_name</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#enlouquecendo...</span>
User.<span style="color:#9900CC;">girls</span>.<span style="color:#9900CC;">contains</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span>, <span style="color:#996600;">&quot;Je%&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">created_since</span><span style="color:#006600; font-weight:bold;">&#40;</span>5.<span style="color:#9900CC;">days</span>.<span style="color:#9900CC;">ago</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">by_first_name</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>:first_name<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><strong>Mesclando finders dinâmicos e escopos</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">boys</span>.<span style="color:#9900CC;">find_all_by_first_name</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Peter&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Note que o finder deve ser o último método na cadeia, pois retorna um Array, onde seus escopos não existem:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">=&gt;</span> User.<span style="color:#9900CC;">find_all_by_first_name</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;A%&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">boys</span>
<span style="color:#CC00FF; font-weight:bold;">NoMethodError</span>: undefined method <span style="color:#996600;">`boys' for #&lt;Array:0x21e7bf0&gt;</span></pre></div></div>

<p><strong>Testando named_scopes</strong></p>
<p>É claro que temos que testar se os escopos estão formando as condições da maneira que desejamos. Existem alguns métodos que ajudam a fazer isso:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">should <span style="color:#996600;">&quot;correctly generate the 'boys' scope&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  expected = <span style="color:#006600; font-weight:bold;">&#123;</span>:conditions <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;gender = ?&quot;</span>, <span style="color:#996600;">&quot;M&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  assert_equal<span style="color:#006600; font-weight:bold;">&#40;</span>expected, User.<span style="color:#9900CC;">boys</span>.<span style="color:#9900CC;">proxy_options</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>Update Fev/2009:</strong> Na verdade, <strong>nunca</strong> teste named_scopes dessa maneira. Quando estamos desenvolvendo com TDD, não nos interessa saber se algo está codificado numa classe mas, sim, se essa classe possui o comportamento esperado. O teste que coloquei acima apenas verifica se há um named_scope declarado no model e isso, definitivamente, não é bom. Segue um outro exemplo de teste:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">setup <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#0066ff; font-weight:bold;">@boys</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  3.<span style="color:#9900CC;">times</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@boys</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> Factory<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:user</span>, <span style="color:#ff3333; font-weight:bold;">:gender</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;M&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Factory<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:user</span>, <span style="color:#ff3333; font-weight:bold;">:gender</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;F&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
should <span style="color:#996600;">&quot;be able to list just the users that are boys&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  assert_equal<span style="color:#006600; font-weight:bold;">&#40;</span>@boys, User.<span style="color:#9900CC;">boys</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Agora sim estamos usando o teste da maneira correta. Não nos importa <strong>como</strong> esse filtro está escrito, apenas se ele nos proporciona o <strong>comportamento</strong> esperado.</p>
<p><strong>Observação:</strong> os exemplos são para ilustrar o que pode ser feito com esse recurso. Tome muito cuidado com os encadeamentos que executar, sempre observando as queries resultantes. Um pequeno deslize pode significar um gargalo significativo. </p>
<p><strong>Leia mais:</strong><br />
<a target="_blank" href="http://www.pathf.com/blogs/2008/06/more-named-scope-awesomeness/">More Named Scope Awesomeness</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/07/30/um-pouco-mais-sobre-named_scopes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Learncast #1: BDD leve com Shoulda &#8211; testando modelos ActiveRecord</title>
		<link>http://www.makemesimple.com/blog/2008/06/27/learncast1-bdd-leve-com-shoulda-testando-modelos-activerecord/</link>
		<comments>http://www.makemesimple.com/blog/2008/06/27/learncast1-bdd-leve-com-shoulda-testando-modelos-activerecord/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 05:10:17 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Learncast]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=132</guid>
		<description><![CDATA[Behavior Driven Development parece ganhar tração constantemente nas comunidades de desenvolvedores de teste. Isso não é à toa: essa &#8220;nova&#8221; mentalidade dá o toque semântico que faltava às técnicas de Test Driven Development. Na comunidade Rails, os três projetos mais conhecidos na área de BDD são RSpec, Shoulda e test/spec. Minha escolha é o Shoulda, [...]]]></description>
			<content:encoded><![CDATA[<p>Behavior Driven Development parece ganhar tração constantemente nas comunidades de desenvolvedores de teste. Isso não é à toa: essa &#8220;nova&#8221; mentalidade dá o toque semântico que faltava às técnicas de Test Driven Development.</p>
<p>Na comunidade Rails, os três projetos mais conhecidos na área de BDD são <a href="http://rspec.info/" target="_blank">RSpec</a>, <a href="http://thoughtbot.com/projects/shoulda/" target="_blank">Shoulda</a> e <a href="http://test-spec.rubyforge.org/test-spec/" target="_blank">test/spec</a>. Minha escolha é o Shoulda, que utilizo <a href="http://giantrobots.thoughtbot.com/2007/4/6/shoulda-coulda-woulda" target="_blank">desde o lançamento</a> com muito sucesso. Há um bom tempo venho &#8220;rascunhando&#8221; um screencast introdutório e, finalmente, ele está pronto. <a href="http://www.makemesimple.com/files/learncast1.mov" target="_blank">Clique aqui para baixá-lo</a> em formato QuickTime.</p>
<p>O objetivo do screencast é apenas mostrar superficialmente o que é Shoulda e como testar funcionalidades de modelos ActiveRecord (como validações e associações). Em breve virão mais alguns cobrindo testes de controllers e mais detalhes sobre o uso do plugin.</p>
<p>Links interessantes:</p>
<p><a href="http://thoughtbot.com/projects/shoulda/" target="_blank">Shoulda</a>: <a href="http://thoughtbot.com/projects/shoulda/tutorial" target="_blank">tutorial</a> | <a href="http://github.com/thoughtbot/shoulda/tree/master">repositório</a> | <a href="http://dev.thoughtbot.com/shoulda/" target="_blank">RDocs</a> | <a href="http://github.com/drnic/ruby-shoulda-tmbundle/tree/master" target="_blank">bundle para TextMate</a></p>
<p>Plugin <a href="http://github.com/thoughtbot/quietbacktrace/tree/master" target="_blank">QuietBacktrace</a></p>
<p>Comentários, críticas e complementos são muito bem-vindos!</p>
<p><strong>Obs</strong>: estou resfriado, mas fiz o possível para deixar o som o mais claro possível. Por favor, avise caso eu não tenha conseguido. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong>: como apontado nos comentários, subi o vídeo sem o som (duh!), mas isso já foi corrigido. Obrigado pelo aviso, pessoal.</p>
<p><strong>Update 2</strong>: <a href="http://makemesimple.com/files/autotest_pack.zip" target="_blank">disponibilizei o script e as imagens que utilizo para o Autotest</a> com o Shoulda em minha máquina, rodando o Leopard. Crie, na pasta home de seu usuário (/Users/&lt;nome_do_seu_usuário&gt;/), uma pasta chamada .autotest_images e copie as duas imagens para lá. Crie, também na home, um arquivo chamado .autotest e preencha-o com o script contido no pacote. Esse script é baseado em um script publicado pelo <a href="http://www.nomedojogo.com/" target="_blank">Carlos Brando</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/06/27/learncast1-bdd-leve-com-shoulda-testando-modelos-activerecord/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
<enclosure url="http://www.makemesimple.com/files/learncast1.mov" length="9642106" type="video/quicktime" />
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.740 seconds -->
