tag:blogger.com,1999:blog-3490264005920656762024-03-08T06:53:51.784-08:00The Ruby UniverseFrancohttp://www.blogger.com/profile/06829892644210965982noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-349026400592065676.post-25194728481084702262007-05-18T13:03:00.000-07:002007-07-26T12:31:55.928-07:00rSpec - behavior driven development framework for RubyMy friend Wayne (who is at RailsConf right now, lucky) introduced me to <a href="http://rspec.rubyforge.org/index.html">rSpec</a>, a behavior driven development framework for Ruby.<br /><br />In short, according to <a href="http://daveastels.com/">Dave Astels</a> (rSpec core developer), if you are doing test driven development (TDD) properly you are already doing behavior driven development (BDD).<br /><br />BDD takes the concept of <span style="font-style: italic;">test first</span> and puts it in a behavior specific domain. Why would someone use a BDD framework over a TDD framework? BDD frameworks like rSpec don't do anything that other unit testing frameworks can't do, they just put it in terms of behavior specification instead of generic assertions. To help the point get across I present this analogy: <blockquote>There is no reason a unit test framework cannot be used to specify behavior of a piece of code, but then again there is a reason why C might not be the best choice of language to implement an object oriented design.</blockquote><br /><br />An example is worth a thousand descriptions: say we want a really cool car, one that can top out around 200 mph and run a quarter mile in 10 seconds (give or take a second.)<br /><br />Using <code>Test::Unit</code> we can specify the behavior thusly:<br /><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">test/unit</span><span class="punct">'</span><br /><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">cool_car</span><span class="punct">'</span><br /><br /><span class="keyword">class </span><span class="class">CoolCarTest</span> <span class="punct"><</span> <span class="constant">Test</span><span class="punct">::</span><span class="constant">Unit</span><span class="punct">::</span><span class="constant">TestCase</span><br /><br /><span class="keyword">def </span><span class="method">setup</span><br /> <span class="attribute">@car</span> <span class="punct">=</span> <span class="constant">CoolCar</span><span class="punct">.</span><span class="ident">new</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">def </span><span class="method">test_quickness</span><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">accellerate</span> <span class="keyword">until</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">distance</span> <span class="punct">>=</span> <span class="number">0.25</span><br /> <span class="ident">assert_in_delta</span> <span class="number">10</span><span class="punct">,</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">time_driven</span><span class="punct">,</span> <span class="number">1.1</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">def </span><span class="method">test_speed</span><br /> <span class="ident">last_speed</span> <span class="punct">=</span> <span class="punct">-</span><span class="number">1</span><br /><br /> <span class="keyword">until</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span> <span class="punct">==</span> <span class="ident">last_speed</span><br /> <span class="ident">last_speed</span> <span class="punct">=</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">accellerate</span><br /> <span class="keyword">end</span><br /><br /> <span class="ident">assert_in_delta</span> <span class="number">200</span><span class="punct">,</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span><span class="punct">,</span> <span class="number">1.1</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">end</span><br /></pre><br />not bad, we specified the behavior of a car that will do what we want, nothing more, nothing less. lets try it again but in rSpec:<br /><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">cool_car</span><span class="punct">'</span><br /><br /><span class="ident">describe</span> <span class="constant">CoolCar</span> <span class="keyword">do</span><br /><br /><span class="ident">before</span><span class="punct">(</span><span class="symbol">:each</span><span class="punct">)</span> <span class="keyword">do</span><br /> <span class="attribute">@car</span> <span class="punct">=</span> <span class="constant">CoolCar</span><span class="punct">.</span><span class="ident">new</span><br /><span class="keyword">end</span><br /><br /><span class="ident">it</span> <span class="punct">"</span><span class="string">should run a quarter mile in 10 +/- 1.1 seconds</span><span class="punct">"</span> <span class="keyword">do</span><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">accellerate</span> <span class="keyword">until</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">distance</span> <span class="punct">>=</span> <span class="number">0.25</span><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">time_driven</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">be_close</span><span class="punct">(</span><span class="number">10</span><span class="punct">,</span> <span class="number">1.1</span><span class="punct">)</span><br /><span class="keyword">end</span><br /><br /><span class="ident">it</span> <span class="punct">"</span><span class="string">should have a top speed of 180 mph or better</span><span class="punct">"</span> <span class="keyword">do</span><br /> <span class="ident">last_speed</span> <span class="punct">=</span> <span class="punct">-</span><span class="number">1</span><br /><br /> <span class="keyword">until</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span> <span class="punct">==</span> <span class="ident">last_speed</span><br /> <span class="ident">last_speed</span> <span class="punct">=</span> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">accellerate</span><br /> <span class="keyword">end</span><br /><br /> <span class="attribute">@car</span><span class="punct">.</span><span class="ident">speed</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">be_close</span><span class="punct">(</span><span class="number">200</span><span class="punct">,</span> <span class="number">1.1</span><span class="punct">)</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">end</span><br /></pre><br />Ahh much nicer.<br /><br />here is <code>cool_car.rb</code>:<br /><pre><span class="keyword">class </span><span class="class">CoolCar</span><br /><br /><span class="ident">attr_reader</span> <span class="symbol">:distance</span><span class="punct">,</span> <span class="symbol">:speed</span><span class="punct">,</span> <span class="symbol">:time_driven</span><br /><br /><span class="keyword">def </span><span class="method">initialize</span><br /> <span class="attribute">@distance</span> <span class="punct">=</span> <span class="number">0.0</span> <span class="comment"># in miles</span><br /> <span class="attribute">@speed</span> <span class="punct">=</span> <span class="number">0.0</span> <span class="comment"># in mph</span><br /> <span class="attribute">@time_driven</span> <span class="punct">=</span> <span class="number">0.0</span> <span class="comment"># in seconds</span><br /><span class="keyword">end</span><br /><br /><span class="comment"># accellerate for one second</span><br /><span class="keyword">def </span><span class="method">accellerate</span><br /> <span class="attribute">@time_driven</span> <span class="punct">+=</span> <span class="number">1</span><br /> <span class="attribute">@speed</span> <span class="punct">+=</span> <span class="number">1</span> <span class="keyword">if</span> <span class="attribute">@speed</span> <span class="punct"><</span> <span class="number">200</span><br /> <span class="attribute">@distance</span> <span class="punct">+=</span> <span class="number">0.025</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">end</span><br /><br /></pre><br />The laws of physics don't really apply, but the spec does! (send me a class for a CoolCar that is a little more realistic and i'll update this, you have a spec).<br /><br />BDD is more than a cute way to write tests in a more natural language, it's a way to specify semantically and syntactically behavior (and only behavior) of of software. From what is demonstrated above we can clearly see that BDD and rSpec are must see stops along the path of agile enlightenment.<br /><br />For a great intro to BDD and rSpec check out Dave Astels' talk:<br /><embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=8135690990081075324&hl=en" flashvars=""> </embed>Francohttp://www.blogger.com/profile/06829892644210965982noreply@blogger.com1tag:blogger.com,1999:blog-349026400592065676.post-36836744559933796062007-05-18T12:27:00.001-07:002007-07-26T12:32:25.653-07:00puts 'hello world'As a casual Ruby user I find the documentation for projects is moving slower than what the actual code the community is using. I also feel that API documentation is less satisfying than examples (at least initially) in the Ruby experience.<br /><br />Implored by Randy Fischer (the technical lead on <a href="http://daitss.fcla.edu/">our project</a>) and Jeff Atwood's <a href="http://www.codinghorror.com/blog/archives/000854.html">post about blogging</a> this blog is meant to keep people informed about what's going on in the Ruby universe.<br /><br />[As Randy says,] I drank the <a href="http://agilemanifesto.org/">agile</a> Kool-Aid, so far its very refreshing.Francohttp://www.blogger.com/profile/06829892644210965982noreply@blogger.com0