<?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>Rabbit Creative &#187; rspec</title>
	<atom:link href="http://www.rabbitcreative.com/category/rspec/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rabbitcreative.com</link>
	<description>ruby, rails, objects and &#60;del&#62;politics&#60;/del&#62; markets</description>
	<lastBuildDate>Tue, 20 Apr 2010 17:15:51 +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>RSpec, meet Flow.</title>
		<link>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/</link>
		<comments>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/#comments</comments>
		<pubDate>Fri, 16 May 2008 00:20:12 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/</guid>
		<description><![CDATA[Flow is the demon that appears after about an hour of using RSpec. He sits on my shoulder and watches me code.
After a few minutes he stands up. I know to turn down the music. He whispers into my ear. I nod in agreement and mouth back a response.
Flow understands my frustration with testing individual [...]]]></description>
			<content:encoded><![CDATA[<p>Flow is the demon that appears after about an hour of using RSpec. He sits on my shoulder and watches me code.</p>
<p>After a few minutes he stands up. I know to turn down the music. He whispers into my ear. I nod in agreement and mouth back a response.</p>
<p>Flow understands my frustration with testing individual methods outside any greater context or usage scenario.</p>
<p>RSpec is a beautiful tool. Leaps and bounds ahead of the standard testing framework built into Rails. It does this, I believe, by allowing you to use more natural language. But it can be be misused. Which is actually closer to abuse, because unless you&#8217;re paying respect to flow, you&#8217;re fucking yourself.</p>
<p><strong>Don&#8217;t test methods outside of the context in which they should be used.</strong> It doesn&#8217;t mean shit to the person reading your code &#8212; even if that person is you.</p>
<p>Your program is a play. Your objects are actors. You are the writer and director. You say action! You say cut! You know all the lines, but it&#8217;s not your job to voice them. You assign those roles to your actors, and they carry it out much better than your sorry ass ever could.</p>
<p>Context. Acknowledge it. If your tests look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'An InterestList'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'upon creation'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'should not be a new record'</span>
    it <span style="color:#996600;">'should be empty'</span>
    it <span style="color:#996600;">'should report having zero Interest objects'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'when adding a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should answer true'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'with one ProductInventoryPrototype in it'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should not be empty'</span>
    it <span style="color:#996600;">'should report having one interest'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'removing a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should answer with the item when that item is removed'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'after removing a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">remove</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should be empty when that item is removed'</span>
    it <span style="color:#996600;">'should report having zero items'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You&#8217;re fucking with the laws of nature, and you will be smitten.</p>
<p>What&#8217;s wrong with it? The
<pre>#before</pre>
<p> code is reinitializing all the steps you&#8217;ve just accomplished.</p>
<p>Make it look like this.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
&nbsp;
      describe <span style="color:#996600;">'It now has one product in it.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
        before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        it <span style="color:#996600;">'It should not be empty.'</span>
        it <span style="color:#996600;">'It should report having one interest.'</span>
&nbsp;
        describe <span style="color:#996600;">'Now we remove a ProductInventoryPrototype.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
          it <span style="color:#996600;">'It should answer with the item when that item is removed.'</span>
&nbsp;
          describe <span style="color:#996600;">'After removing a ProductInventoryPrototype,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
            before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
              <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">remove</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
            it <span style="color:#996600;">'it should be empty when that item is removed.'</span>
            it <span style="color:#996600;">'it should report having zero items'</span>
&nbsp;
          <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Of primary importance is a subtle point. I didn&#8217;t illustrate it in the two examples above, but I will now:</p>
<p>Before:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
      it <span style="color:#996600;">'It should not be empty.'</span>
      it <span style="color:#996600;">'It should report having one interest.'</span>
...</pre></div></div>

<p>After:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
&nbsp;
      describe <span style="color:#996600;">' At which point'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
        it <span style="color:#996600;">'it should not be empty.'</span>
        it <span style="color:#996600;">'it should report having one interest.'</span>
...</pre></div></div>

<p>On the surface it&#8217;s just another level of nesting. After meditation, you realize you are <em>first</em> testing the object&#8217;s answer to your message. <em>Second</em>, you are testing the state of the universe after that action is made. The difference is subtle, but important. If you don&#8217;t understand the importance, recall the indifference you felt when you first saw RSpec: <em>it&#8217;s Rails&#8217; standard test framework with different words thrown in.</em></p>
<p>You were wrong then and you&#8217;re wrong now.</p>
<blockquote><p>Words offer the means to meaning, and for those who will listen, the enunciation of truth. &#8211; V</p></blockquote>
<p>If an object&#8217;s answer to the message passed violates expectations, flow stops. You know, not that a <em>method</em> is broken, but that <em>flow</em> is broken.</p>
<p>Of secondary importance is that your
<pre>#before</pre>
<p> methods are no longer redundant.</p>
<p>The result of running your tests now looks like:</p>
<pre>
When working with an InterestList, it must first be created. It should not be a new record. (Not Yet Implemented)
When working with an InterestList, it must first be created. It should be empty. (Not Yet Implemented)
When working with an InterestList, it must first be created. It should report having zero Interest objects. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. To which it should answer true. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. It should not be empty. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. It should report having one interest. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. It should answer with the item when that item is removed. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. After removing a ProductInventoryPrototype, it should be empty when that item is removed. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. After removing a ProductInventoryPrototype, it should report having zero items (Not Yet Implemented)
</pre>
<p>This is easier to read and understand than a series of isolated tests. You&#8217;re made aware of the context in which each test is being run, which is priceless when you&#8217;re attempting to understand the system from a high level.</p>
<p><strong>Congratulations.</strong> You are no longer a moron coding outside the realm of the context in which your code lives.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
