<?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; Test-Driven Development</title>
	<atom:link href="http://www.makemesimple.com/blog/category/test-driven-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.makemesimple.com/blog</link>
	<description>Conhecimento nunca é o bastante</description>
	<lastBuildDate>Wed, 28 Apr 2010 21:28:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cuidado com o DRY nos seus testes</title>
		<link>http://www.makemesimple.com/blog/2009/09/02/cuidado-com-o-dry-nos-seus-testes/</link>
		<comments>http://www.makemesimple.com/blog/2009/09/02/cuidado-com-o-dry-nos-seus-testes/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:31:21 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=283</guid>
		<description><![CDATA[Don&#8217;t Repeat Yourself é um dos princípios de desenvolvimento de software mais &#8220;badalados&#8221; nos últimos tempos. O problema é que, como tudo que se torna popular, isso acaba sendo abusado. Numa tentativa de criar código limpo é comum criar código difícil de entender. Isso afeta principalmente os testes.
Testes devem ser extremamente legíveis. Não deve existir [...]]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don&#8217;t Repeat Yourself</a> é um dos princípios de desenvolvimento de software mais &#8220;badalados&#8221; nos últimos tempos. O problema é que, como tudo que se torna popular, isso acaba sendo abusado. Numa tentativa de criar código limpo é comum criar código difícil de entender. Isso afeta principalmente os testes.</p>
<p>Testes devem ser extremamente legíveis. Não deve existir sobrecarga cognitiva, isto é, não deve ser necessário entender o código do teste para então entender o comportamento que ele especifica &#8211; isso deve ficar claro rapidamente. Exemplos de sobrecarga são a necessidade de &#8220;ficar pulando&#8221; entre vários arquivos ou &#8220;descriptografando&#8221; lógica mágica para entender o código do teste.</p>
<p>É fácil, então, identificar dois tipos de recursos que podem causar problemas no entendimento dos testes &#8211; há uma tênue linha separando o bom e o mal uso deles: macros e &#8220;magia negra&#8221; em forma de código Ruby.</p>
<p>Macros devem ser utilizadas com muito cuidado. É interessante utilizar macros que encapsulam código simples para economizar tempo na criação dos testes, como essa macro para especificar ações autenticadas com o Authlogic:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> login_as<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
  activate_authlogic   <span style="color:#008000; font-style:italic;">#this is from Authlogic::TestCase</span>
  UserSession.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span>:email <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">email</span>, <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">password</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></pre></div></div>

<p>Macros com muito código ou que utilizam outras macros devem ser evitadas.</p>
<p>Um problema provavelmente mais grave é a utlização de algumas técnicas de &#8220;magia negra&#8221; no código. Aquela técnica super obscura e bacana envolvendo o Enumerable que você viu num blog esses dias não deve ser usada nos testes (nem na lógica de negócios, na minha opinião): foque sempre nos idiomas comuns da linguagem. Por simples falha da minha memória agora, segue um exemplo bobo, mas válido:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># truque menos conhecido</span>
<span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>this is a test<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#996600;">&quot;, &quot;</span>    <span style="color:#008000; font-style:italic;">#=&gt; &quot;this, is, a, test&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># idioma comum</span>
<span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>this is a test<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>    <span style="color:#008000; font-style:italic;">#=&gt; &quot;this, is, a, test&quot;</span></pre></div></div>

<p>Os testes, quando usados corretamente, também são a porta de entrada de novos desenvolvedores ao código já existente na aplicação. Pode ser que sua equipe seja formada por Rubistas experientes que conheçam todos os truques envolvidos, mas a adaptação de um profissional com menos experiência na linguagem pode ser muito facilitada por testes com código simples e altamente legível, mesmo que isso &#8220;custe&#8221; alguma repetição ou uso de construções mais comuns.</p>
<p>A conclusão é: em todo seu código e principalmente nos testes, evite o uso de macros que escondem muito código ou lógica relevante ao comportamento especificado e também prefira idiomas comuns, mesmo que você saiba técnicas &#8220;ninja&#8221; da linguagem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/09/02/cuidado-com-o-dry-nos-seus-testes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Você confia em métricas?</title>
		<link>http://www.makemesimple.com/blog/2009/08/31/voce-confia-em-metricas/</link>
		<comments>http://www.makemesimple.com/blog/2009/08/31/voce-confia-em-metricas/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 17:29:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=154</guid>
		<description><![CDATA[Usar métricas no seu código é uma boa prática. Existem várias ferramentas que provém métricas muito interessantes e ferramentas, como o metric_fu, que integram várias delas.
No entanto, é preciso ter bastante cuidado. Métricas são como muletas: muito úteis quando você não consegue andar sem a ajuda delas mas, se você utilizá-las sem necessidade, vai enfraquecer [...]]]></description>
			<content:encoded><![CDATA[<p>Usar métricas no seu código é uma boa prática. Existem várias ferramentas que provém métricas muito interessantes e ferramentas, como o metric_fu, que integram várias delas.</p>
<p>No entanto, é preciso ter bastante cuidado. Métricas são como muletas: muito úteis quando você não consegue andar sem a ajuda delas mas, se você utilizá-las sem necessidade, vai enfraquecer suas pernas.</p>
<p>Um bom exemplo disso é uma métrica muito utilizada por quem escreve testes: a cobertura de código. É uma ferramenta muito útil quando é preciso &#8220;correr atrás&#8221; do prejuízo, isto é, adicionar testes a código sem cobertura. Nesse caso, é prática comum estabelecer uma porcentagem de cobertura a ser atingida dentro de um prazo limitado. Mas, se você pratica BDD/TDD consistentemente e não deixa código importante sem cobertura, é realmente necessário confirmar isso com um gráfico ou uma porcentagem? </p>
<p>O uso e confiança cega em métricas mesmo sem necessidade de um amparo como esse pode levar à má aplicação da técnica do desenvolvimento guiado por testes, já que ela passa a ser baseada em um número artificial &#8211; é muito fácil ter 100% de cobertura de código com uma suíte de testes ruim. Antes uma suite boa mas que, conscientemente, não passa por cada linha de código do que uma suite que execute cada linha, mas seja um lixo como especificação e ferramenta de refactoring.</p>
<p>Mais um exemplo de fragilidade fica claro no famoso e cantado aos quatro ventos <em>code to test ratio</em>: ao utilizar um framework de testes verboso, é fácil obter uma razão de linhas de teste por linhas de código muito maior do que utilizando um framework mais compacto ou macros. Me desculpe quem utiliza e divulga esse número como algum indicativo de qualidade, mas essa medida é simplesmente ridícula, além de totalmente ilusória.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/08/31/voce-confia-em-metricas/feed/</wfw:commentRss>
		<slash:comments>0</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: &#8220;Não [...]]]></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>Testes devem revelar a intenção do código</title>
		<link>http://www.makemesimple.com/blog/2009/05/08/testes-devem-revelar-a-intencao-do-codigo/</link>
		<comments>http://www.makemesimple.com/blog/2009/05/08/testes-devem-revelar-a-intencao-do-codigo/#comments</comments>
		<pubDate>Fri, 08 May 2009 22:04:13 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=138</guid>
		<description><![CDATA[Essa frase não é novidade para ninguém &#8211; ou, pelo menos, não deveria ser. No entanto, é muito mais difícil fazer isso acontecer do que falar sobre o assunto. 
É muito bom que a mentalidade de testes esteja sendo cada vez mais difundida. Com isso, desenvolvem-se as abordagens às práticas de desenvolvimento orientado por testes [...]]]></description>
			<content:encoded><![CDATA[<p>Essa frase não é novidade para ninguém &#8211; ou, pelo menos, não deveria ser. No entanto, é muito mais difícil fazer isso acontecer do que falar sobre o assunto. </p>
<p>É muito bom que a mentalidade de testes esteja sendo cada vez mais difundida. Com isso, desenvolvem-se as abordagens às práticas de desenvolvimento orientado por testes como, por exemplo, os frameworks. Enquanto eles se tornam cada vez mais extensíveis, eficientes e com DSLs mais limpas e bonitas, muitas pessoas esquecem que, independentemente da ferramenta, da sintaxe e da abordagem técnica a ser utilizada, a intenção do código desenvolvido é que deve ficar explícita.</p>
<p><strong>Observação</strong>: ao longo desse texto, utilizarei a expressão &#8220;desenvolvimento orientado por testes&#8221;, mas você pode substituir por &#8220;desenvolvimento orientado por comportamento&#8221; ou qualquer abordagem similar.</p>
<h4>O que é a intenção do código?</h4>
<p>A intenção do código tem tudo a ver com algo que vem sendo muito discutido: o comportamento do software. Uma definição de comportamento é &#8220;<em>a resposta observável de um sistema a um estímulo</em>&#8220;. Logo, em última análise, podemos dizer que o que importa é verificar se a resposta observável de um componente de software é a esperada, dado um ou mais estímulos pré-definidos.</p>
<p>Em alguns casos isso significa apenas definir um estado, chamar algum método e verificar o resultado. Em outros, significa verificar também a propagação dos efeitos em outros objetos (caso onde os mocks são muito úteis). Isso vai depender do componente em desenvolvimento e da abordagem utilizada.</p>
<h4>Como?</h4>
<p>A pergunta é: como testes ajudam a revelar a intenção do código? </p>
<p>Se você escrever um monte de código confuso e, após isso, resolver escrever alguns testes para validar esse trabalho, esses testes não vão ajudar em nada. Mas, se utilizar testes para orientar seu processo de desenvolvimento, descobrirá o papel fundamental que eles terão para criar código claro, fácil de entender, utilizar e modificar. Ao especificar um cenário (o estado pré-definido onde ocorrerá o estímulo), fica muito mais simples projetar e verificar o comportamento necessário.</p>
<p>Geralmente, ao escrever testes antes da implementação, obtêm-se outros benefícios, tais como: uso de boa nomenclatura, simplicidade e facilidade no refactoring. Tudo isso deve-se ao fato de que, ao praticar o desenvolvimento orientado por testes, você efetivamente <strong>pensa</strong> mais sobre o que vai escrever, antes de o fazer.</p>
<h4>Exemplo</h4>
<p>Vou tentar exemplificar os passos de criação de um componente simples com e sem testes para orientar a implementação. Assim, ao final, teremos uma perspectiva melhor dos efeitos do processo.</p>
<p>Quero escrever uma aplicação para cadastrar minha coleção de filmes. Preciso de uma classe que representará o filme:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Movie
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:title</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Isso é o suficiente para o exemplo.</p>
<p>Agora vamos iniciar o processo de implementação da classe responsável pelo gerenciamento da coleção. Primeiro, sem teste algum.</p>
<p>Sei que preciso de uma classe que possua uma lista de filmes e permita que eu posso adicionar, remover, procurar e listar todos os filmes. Vamos lá:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MovieShelf
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:movies</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#0066ff; font-weight:bold;">@movies</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> lookup<span style="color:#006600; font-weight:bold;">&#40;</span>movie<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@movies</span>.<span style="color:#9900CC;">detect</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>m<span style="color:#006600; font-weight:bold;">|</span> m == movie<span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> list
    <span style="color:#0066ff; font-weight:bold;">@movies</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>movie<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> movie.<span style="color:#9900CC;">title</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>Ok, muito simples. Em dois minutos está pronto. Um exemplo de uso (no irb):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf = MovieShelf.<span style="color:#9900CC;">new</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;MovieShelf:0x36eb88 @movies=[]&gt;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> m = Movie.<span style="color:#9900CC;">new</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;Movie:0x33b328&gt;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> m.<span style="color:#9900CC;">title</span> = <span style="color:#996600;">&quot;Juno&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Juno&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> m2 = Movie.<span style="color:#9900CC;">new</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;Movie:0x39968&gt;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> m2.<span style="color:#9900CC;">title</span> = <span style="color:#996600;">&quot;Transformers&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Transformers&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">movies</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> m
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#008000; font-style:italic;">#&lt;Movie:0x33b328 @title=&quot;Juno&quot;&gt;]</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">movies</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> m2
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#008000; font-style:italic;">#&lt;Movie:0x33b328 @title=&quot;Juno&quot;&gt;, #&lt;Movie:0x39968 @title=&quot;Transformers&quot;&gt;]</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">list</span>
Juno
Transformers
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#008000; font-style:italic;">#&lt;Movie:0x33b328 @title=&quot;Juno&quot;&gt;, #&lt;Movie:0x39968 @title=&quot;Transformers&quot;&gt;]</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">lookup</span> m2
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;Movie:0x39968 @title=&quot;Transformers&quot;&gt;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">movies</span>.<span style="color:#9900CC;">delete</span> m2
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;Movie:0x39968 @title=&quot;Transformers&quot;&gt;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> shelf.<span style="color:#9900CC;">list</span>
Juno
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#008000; font-style:italic;">#&lt;Movie:0x33b328 @title=&quot;Juno&quot;&gt;]</span></pre></div></div>

<p>Tudo bem, funciona e parece estar de acordo com os requisitos. Mas o código não está muito consistente. A coleção de filmes, que na prática é um objeto da classe Array, está exposta e pode ser manipulada diretamente. Isso pode ser muito ruim caso algum método da classe MovieShelf faça ações adicionais ao operar sobre a coleção. A nomenclatura também não é muito clara, entre outros pequenos problemas. Também não gostei da forma como estou criando os objetos que representam os filmes.</p>
<p>Agora, vamos começar com uma pequena especificação do que é preciso. Com isso, vou ter mais tempo para pensar em bons nomes e numa forma de uso limpa e direta.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">context <span style="color:#996600;">&quot;a movie shelf&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  setup <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0066ff; font-weight:bold;">@shelf</span> = MovieShelf.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  should <span style="color:#996600;">&quot;let the user store a movie&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    juno = Movie.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Juno&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    shelf.<span style="color:#9900CC;">store</span> juno
    assert shelf.<span style="color:#9900CC;">contains</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>juno<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></pre></div></div>

<p>Somente estabelecendo essa primeira expectativa quanto ao comportamento do componente, já temos idéia de um início de implementaçã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> Movie
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:title</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>title<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">title</span> = title
  <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> MovieShelf
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#0066ff; font-weight:bold;">@movies</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> store<span style="color:#006600; font-weight:bold;">&#40;</span>movie<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@movies</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> movie
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> contains?<span style="color:#006600; font-weight:bold;">&#40;</span>movie<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@movies</span>.<span style="color:#9966CC; font-weight:bold;">include</span>? movie
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Continuando:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">context <span style="color:#996600;">&quot;a movie shelf&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  setup <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0066ff; font-weight:bold;">@shelf</span> = MovieShelf.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  should <span style="color:#996600;">&quot;show how many movies are stored&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    juno = Movie.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Juno&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    transformers = Movie.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Transformers&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    shelf.<span style="color:#9900CC;">store</span> juno
    shelf.<span style="color:#9900CC;">store</span> transformers
    assert_equal <span style="color:#006666;">2</span>, shelf.<span style="color:#9900CC;">movies_count</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Implementando:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MovieShelf
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#0066ff; font-weight:bold;">@movies</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> store<span style="color:#006600; font-weight:bold;">&#40;</span>movie<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@movies</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> movie
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> contains?<span style="color:#006600; font-weight:bold;">&#40;</span>movie<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@movies</span>.<span style="color:#9966CC; font-weight:bold;">include</span>? movie
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> movies_count
    <span style="color:#0066ff; font-weight:bold;">@movies</span>.<span style="color:#9900CC;">size</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>É claro que o exemplo é bem bobo, mas perceba como a interface fica melhor e também como vamos descobrindo novas funcionalidades ao longo do processo de especificação. Este é um dos principais benefícios do desenvolvimento orientado por testes: interfaces ricas através de código modular, flexível e de intenção clara.</p>
<p>Não vou continuar o exemplo com as demais funcionalidades para não alongar ainda mais o artigo. Acredito que consegui expor aqui a importância da intenção do código e como deixá-la clara e fácil de entender.</p>
<p>O que você pensa sobre isso? Deixe sua opinião, comentário, exemplo, crítica ou sugestão. <img src='http://www.makemesimple.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Leia também:</p>
<ul>
<li><a href="http://www.informit.com/articles/article.aspx?p=357688" target="_blank">Test Driven Development: Programming by Intention</a></li>
<li><a href="http://blog.aslakhellesoy.com/2006/12/11/the-bdd-cargo-cult" target="_blank">The BDD cargo culting</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/05/08/testes-devem-revelar-a-intencao-do-codigo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Evitando over-stubbing com Mocha</title>
		<link>http://www.makemesimple.com/blog/2009/03/18/evitando-over-stubbing-com-mocha/</link>
		<comments>http://www.makemesimple.com/blog/2009/03/18/evitando-over-stubbing-com-mocha/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 16:45:29 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Anúncios]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=191</guid>
		<description><![CDATA[Não é segredo que não sou &#8220;fã&#8221; da maneira como a comunidade de desenvolvedores utiliza mocks e stubs. A meu ver, trata-se de mal uso de uma ferramenta muito útil.
Com esse tipo de uso surgem alguns problemas, tais como over-mocking e over-stubbing, ou seja, o uso abusivo de mocks e stubs. O abuso de mocks [...]]]></description>
			<content:encoded><![CDATA[<p>Não é segredo que não sou &#8220;fã&#8221; da maneira como a comunidade de desenvolvedores utiliza mocks e stubs. A meu ver, trata-se de mal uso de uma ferramenta muito útil.</p>
<p>Com esse tipo de uso surgem alguns problemas, tais como over-mocking e over-stubbing, ou seja, o uso abusivo de mocks e stubs. O abuso de mocks torna seus testes quebradiços, isto é, testes que falham sem que haja alteração de comportamento do componente sob verificação. O abuso de stubs torna seus testes fracos, isto é, testes que saem de sincronia com o código, verificando comportamento que já não é real, mas continuam passando.</p>
<p>Um exemplo de abuso de mocks:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">&quot;should be successful&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  Account.<span style="color:#9900CC;">expects</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:new</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:current_user</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@user</span>, <span style="color:#ff3333; font-weight:bold;">:first_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Test&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Test&quot;</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>@account<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0066ff; font-weight:bold;">@account</span>.<span style="color:#9900CC;">expects</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:login_method</span>=<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">CONFIG::LOGIN::OpenID</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0066ff; font-weight:bold;">@account</span>.<span style="color:#9900CC;">expects</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:has_email_and_password</span>=<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">at_least_once</span>
  <span style="color:#0066ff; font-weight:bold;">@account</span>.<span style="color:#9900CC;">expects</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:has_openid</span>=<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">twice</span>
  do_edit
  response.<span style="color:#9900CC;">should</span> be_success
  response.<span style="color:#9900CC;">should</span> render_template<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;edit&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Note que até métodos de atribuição são colocados sob expectativas. Se a implementação sofrer uma alteração simples, fazendo, por exemplo, com que algum desses métodos não seja mais chamado, mesmo que não haja qualquer modificação no comportamento, o teste falhará.</p>
<p>Um exemplo do abuso de stubs:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">&quot;has been modified a lot of times&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  Dependency.<span style="color:#9900CC;">stubs</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a_method</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  NoLongerADependency.<span style="color:#9900CC;">stubs</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:something</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:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  AnotherDependency.<span style="color:#9900CC;">stubs</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:nonexistent_method</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>
  MyClass.<span style="color:#9900CC;">new</span>.<span style="color:#9900CC;">do_something</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Com esse tipo de abordagem, você pode acabar com problemas como fazer stubs de métodos que não existem mais ou até mesmo de objetos que já não são mais uma dependência.</p>
<p>Uma forma de evitar isso com o Mocha (além, é claro, de estudar o uso correto das ferramentas) é utilizar algumas configurações providas pelo framework através de sua classe Configuration:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">prevent</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:stubbing_non_existent_method</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#impede stubbing de métodos inexistentes</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">prevent</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:stubbing_method_unnecessarily</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#impede stubbing de métodos não utilizados</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">prevent</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:stubbing_non_public_method</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#impede stubbing de métodos não-públicos</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">prevent</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:stubbing_method_on_non_mock_object</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#impede stubbing em objetos &quot;reais&quot;</span></pre></div></div>

<p>Nos exemplos acima, caso encontre um dos usos &#8220;indevidos&#8221;, o Mocha lançará uma exceção do tipo Mocha::StubbingError. Isso ocorre por termos utilizado o método prevent. Há outras configurações possíveis, sendo providos três nívels de configuração:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># padrão - permite a condição</span>
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">allow</span><span style="color:#006600; font-weight:bold;">&#40;</span>condition<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># apenas emite um aviso quando ocorre a condição</span>
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">warn_when</span><span style="color:#006600; font-weight:bold;">&#40;</span>condition<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># lança um erro quando ocorre a condição</span>
<span style="color:#6666ff; font-weight:bold;">Mocha::Configuration</span>.<span style="color:#9900CC;">prevent</span><span style="color:#006600; font-weight:bold;">&#40;</span>condition<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Essas configurações podem ser um auxílio para o aprendizado do uso correto e equilibrado da ferramenta.</p>
<p>Leia mais:<br />
<a href="http://mocha.rubyforge.org/classes/Mocha/Configuration.html" target="_blank">Mocha::Configuration RDoc</a><br />
<a href="http://blog.floehopper.org/articles/2009/02/09/mocha-configuration" target="_blank">Mocha Configuration &#8211; James Mead</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2009/03/18/evitando-over-stubbing-com-mocha/feed/</wfw:commentRss>
		<slash:comments>7</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 açúcar [...]]]></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 programação, [...]]]></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 ser [...]]]></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>High Five: five tips on testing with Rails</title>
		<link>http://www.makemesimple.com/blog/2008/05/05/high-five-five-tips-on-testing-with-rails/</link>
		<comments>http://www.makemesimple.com/blog/2008/05/05/high-five-five-tips-on-testing-with-rails/#comments</comments>
		<pubDate>Mon, 05 May 2008 05:48:10 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[In English]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/2008/05/05/high-five-five-tips-on-testing-with-rails/</guid>
		<description><![CDATA[Testing is a very important aspect of Rails programming. The framework makes testing really easy, eliminating some excuses you could have for not testing your applications. Here&#8217;s my five tips for testing with Rails:

Embrace the TDD cycle: this one isn&#8217;t Rails related, but is very important. You can write your code first and test it [...]]]></description>
			<content:encoded><![CDATA[<p>Testing is a very important aspect of Rails programming. The framework makes testing really easy, eliminating some excuses you could have for not testing your applications. Here&#8217;s my five tips for testing with Rails:</p>
<ul>
<li><span class="Apple-style-span" style="font-weight: bold">Embrace the TDD cycle</span>: this one isn&#8217;t Rails related, but is very important. You can write your code first and test it after and you&#8217;ll get some benefits, but <a href="http://en.wikipedia.org/wiki/Test_driven_development" target="_blank">Test-Driven Development</a> really leverages the power of this automated testing. By writing your tests first you get low <a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)" target="_blank">coupling</a> and high <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank">cohesion</a> through a better interface (API) design. Moreover, by following the red-green-refactor cycle you&#8217;ll always know when you&#8217;re done and will avoid <a href="http://en.wikipedia.org/wiki/Functionality_creep" target="_blank">scope creep</a>.</li>
<li><span class="Apple-style-span" style="font-weight: bold"><del datetime="2009-08-28T15:31:49+00:00">Test your helpers</span>: plain and simple. <a href="http://www.pragprog.com/titles/fr_rr/rails-recipes" target="_blank">Rais Recipes</a> has a recipe about it and, with Edge Rails, <a href="http://blog.codefront.net/2008/04/20/living-on-the-edge-of-rails-17/" target="_blank">testing helpers got easier</a></del>.</li>
<li><span class="Apple-style-span" style="font-weight: bold">Overmocking results in brittle tests</span>:and brittle tests are a bad thing. Many people just mock and stub everything. By doing this you&#8217;re coupling your tests to the inner details of the tested code instead of the result of its execution. <a href="http://giantrobots.thoughtbot.com/2007/3/17/battle-royale-testing" target="_blank">You can see an example here </a>(and subscribe to that blog&#8217;s feed, it&#8217;s very good).</li>
<li><span class="Apple-style-span" style="font-weight: bold">Watch out on your way to BDD</span>: <a href="http://behaviour-driven.org/" target="_blank">Behavior-Driven Development</a> is in vogue within the Rails community. Be careful. Just like you can <a href="http://www.codinghorror.com/blog/archives/000272.html" target="_blank">write Fortran in any language</a>, you can use something like RSpec and still not do BDD. BDD is about a shift in the way you think about tests, not about tools by themselves. You can use Test::Unit and do BDD. Tools like <a href="http://rspec.info/" target="_blank">RSpec</a> and <a href="http://thoughtbot.com/projects/shoulda" target="_blank">Shoulda</a> (my personal choice) are facilitators, they don&#8217;t guarantee anything.</li>
<li><span class="Apple-style-span" style="font-weight: bold">One assertion per test</span>: this is one of that tips that seems inoffensive but once you&#8217;re doing helps a lot. Why? <a href="http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html" target="_blank">Jay Fields can explain better than me</a>.</li>
</ul>
<p>And that&#8217;s it. Five quick and simple tips that I hope will help you. Feel free to share your own tips in the comments. This article is my entry to the <a href="http://railscasts.com/contest" target="_blank">Railscasts&#8217; 100th episode contest</a>. Take some time to visit the site, it&#8217;s really good.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makemesimple.com/blog/2008/05/05/high-five-five-tips-on-testing-with-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

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