<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Talk Like A Duck: Tag Rspec</title>
    <link>http://talklikeaduck.denhaven2.com/articles/tag/rspec</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In Ruby, it's not the dog, it's the tricks!</description>
    <item>
      <title>RSpec Anti-Pattern - Don't Set @controller yourself</title>
      <description>&lt;p&gt;I was adding to an existing controller today at work and I was stumped because one of the examples in its controller spec was failing due to an exception thrown while rendering a view.&lt;/p&gt;
&lt;p&gt;Normally RSpec controller tests, which are usually used to specify controller logic, bypass view rendering unless you specifically use the integrate_views method in the example group. The idea is that you should use view specs to specify the logic and output of views.&lt;/p&gt;
&lt;p&gt;Since I was working in existing code, which pre-existed my being here, I&amp;#8217;d followed some of the existing example groups in the file.  These would typically look something like this:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="constant"&gt;HobbitController&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;doing something&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;

    &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="attribute"&gt;@controller&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;HobbitController&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
      &lt;span class="comment"&gt;#.. more setup stubbing etc.&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

   &lt;span class="comment"&gt;#examples&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I finally realized that that first line in the before block was clobbering RSpecs ability to control whether or not views should be rendered.  RSpec actually creates the controller instance variable for you, and extends it with a module which overrides the render method to allow integrate_views to control the rendering while allowing the expect_render expectation to work whether or not rendering actually happens.&lt;/p&gt;
&lt;p&gt;So I&amp;#8217;ve got a new task to clean up all the other controller specs.&lt;/p&gt;</description>
      <pubDate>Wed, 26 Mar 2008 17:30:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8ed18916-a083-41a8-9d17-75820dc1c273</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2008/03/26/rspec-anti-pattern-dont-set-controller-yourself</link>
      <category>rails</category>
      <category>Rspec</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/492</trackback:ping>
    </item>
    <item>
      <title>Validating RSS Feeds with RSpec</title>
      <description>&lt;p&gt;One of my current Rails projects involves generating an RSS feed.  While I was working on this the other night, it seemed to be working, so I deployed it to the staging server. Everything looked fine. If I fetched it with Firefox, the browser offered to let me subscribe to the feed with Google Reader, and if I used Safari I'd see a nice view of the feed just like I expected.&lt;/p&gt;
&lt;p&gt;So I sent a note via our campfire to check it out, and a colleague replied that &lt;strong&gt;his&lt;/strong&gt; Safari was saying that it was in an invalid format.&lt;/p&gt;
&lt;p&gt;So I went to the &lt;a href="http://validator.w3.org/feed/"&gt;W3 RSS Feed Validation Service&lt;/a&gt; and worked through the validation issues, after which his browser was as happy as mine.&lt;/p&gt;
&lt;p&gt;Of course, having been through that, I wanted to make sure that RSS validation was covered in the specs for the project.&lt;/p&gt;
&lt;p&gt;I went looking for an existing RSpec matcher, and found &lt;a href="http://www.anodyne.ca/2007/09/28/rspec-custom-matchers-and-be_valid_xhtml/"&gt;a matcher to validate XHTML&lt;/a&gt; but nothing for RSS.&lt;/p&gt;
&lt;p&gt;I then found the &lt;a href="http://feedvalidator.rubyforge.org/"&gt;feedvalidator gem&lt;/a&gt; which provides a Ruby interface to the SOAP interface to the W3 feed validator.  You would think that W3 would be providing a REST interface!  The gem already provides assertions for use with Test::Unit, so I just built an RSpec matcher.&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;notextile&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;BeValidFeed&lt;/span&gt;
  &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;feed_validator&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;tmpdir&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;md5&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;matches?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;validity_checks_disabled?&lt;/span&gt;
    &lt;span class="ident"&gt;v&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;W3C&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;FeedValidator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="ident"&gt;fragment&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;body&lt;/span&gt;
    &lt;span class="ident"&gt;filename&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;join&lt;/span&gt; &lt;span class="constant"&gt;Dir&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="ident"&gt;tmpdir&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;feed.&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="constant"&gt;MD5&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;md5&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;fragment&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;
    &lt;span class="keyword"&gt;begin&lt;/span&gt;
      &lt;span class="ident"&gt;response&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt; &lt;span class="ident"&gt;filename&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;Marshal&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;load&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;
      &lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  	&lt;span class="keyword"&gt;rescue&lt;/span&gt;   
      &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;validate_data&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;fragment&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="attribute"&gt;@failure&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; could not access w3 validator to validate the feed.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
      &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt; &lt;span class="ident"&gt;filename&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;w+&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;Marshal&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;dump&lt;/span&gt; &lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;
  	&lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;valid?&lt;/span&gt;   
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;description&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;be valid xhtml&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;failure_message&lt;/span&gt;
   &lt;span class="attribute"&gt;@failure&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; expected xhtml to be valid, but validation produced these errors:&lt;span class="escape"&gt;\n&lt;/span&gt; &lt;span class="expr"&gt;#{@message}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;negative_failure_message&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; expected to not be valid, but was (missing validation?)&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;private&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;validity_checks_disabled?&lt;/span&gt;
      &lt;span class="constant"&gt;ENV&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;NONET&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;be_valid_feed&lt;/span&gt;
  &lt;span class="constant"&gt;BeValidFeed&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I saved this as spec/be_valid_feed.rb&lt;/p&gt;

&lt;p&gt;And in a view or controller spec, I can include this file, and test a response with:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;response.should be_valid_feed&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you use this in a controller spec, you will need to tell RSpec to integrate_views, or you won't have much of a feed to check.  If you use nested example groups, integrate_views needs to be inside the inner group.&lt;/p&gt;

</description>
      <pubDate>Fri, 08 Feb 2008 10:38:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0b27f7ba-403b-48c5-9833-2fd2b5d73fa8</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2008/02/08/validating-rss-feeds-with-rspec</link>
      <category>ruby</category>
      <category>best_practices</category>
      <category>rails</category>
      <category>Rspec</category>
      <category>rss</category>
      <category>validation</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/486</trackback:ping>
    </item>
    <item>
      <title>Why I Don't Mind Using RSpec - In Fact I've Come to Love It.</title>
      <description>&lt;p&gt;About a year ago when I first encountered RSpec, I thought that the idea sounded good, but I was concerned about how much the implementation at that time pushed new methods into Object and Kernel. It felt to me as though it could interfere with the code being specified/tested. Indeed back then there were some problems when RSpec and Rails bumped heads over the use of certain Ruby metaprogramming techniques.  I&amp;#8217;d been a &lt;span class="caps"&gt;TDD&lt;/span&gt; user advocate for many years, heck I was there right after Kent Beck, &amp;#8220;test-infected&amp;#8221; Erich Gamma and sat in on some of their early pairing sessions during an annual &lt;span class="caps"&gt;OTI&lt;/span&gt; company technical conference at Montebello in Quebec, when JUnit was in it&amp;#8217;s infancy.  The cleaner language of RSpec did have it&amp;#8217;s attractions, particularly in trying to get across the idea to newcomers that &lt;span class="caps"&gt;TDD&lt;/span&gt; was really writing mini-specifications rather than tests, which helps put them in the right mindset, but for those of us who had already crossed that paradigm shift, or been born on the right side of it, it didn&amp;#8217;t seem so important.&lt;/p&gt;


	&lt;p&gt;Since then the RSpec implementation has matured, and after talking to David Chelimsky and Dave Astels at RubyConf, I decided to give it another look, and, armed with a new perspective on the use of mocks and stubs to isolate specifications and tests in &lt;span class="caps"&gt;BDD&lt;/span&gt;/TDD, I quickly became a convert.  I still use other frameworks as external requirements dictate, but RSpec has become my first choice.&lt;/p&gt;


	&lt;p&gt;These days, though the choice of testing/specification framework seems to have become one of those religious issues which divide the community, almost as much as emacs vs. vim vs. textmate.  I run into people all the time who reject RSpec because it&amp;#8217;s &amp;#8220;too magical!&amp;#8221;  Although I&amp;#8217;ve never been able to get them to expand on that thought. Perhaps it&amp;#8217;s based on the kind of concerns I had about it at first, maybe it&amp;#8217;s something else.  I&amp;#8217;d love to have it explained.&lt;/p&gt;


	&lt;p&gt;And like advocates do, other arguments get expressed, some of which don&amp;#8217;t get the scrutiny they deserve.&lt;/p&gt;


	&lt;p&gt;For example, a few days ago Rob Sanheim, someone I know and respect, wrote about why &lt;a href="http://robsanheim.com/2008/01/25/why-i-use-testspec-over-rspec/"&gt;he eschews RSpec for Test::Spec&lt;/a&gt;. His basic, quite brief argument is that because RSpec is 10 times bigger in terms of lines of code than Test::Spec it must be worse.&lt;/p&gt;


&lt;h2&gt;How to Lie with Statistics&lt;/h2&gt;
Nice statistics, but back when I was in college, one of the must-read books was &amp;#8220;How to Lie with Statistics&amp;#8221;.  Given the right pick of statistics you can prove anything.

	&lt;p&gt;First off I think that Rob was unfair to lump the lib and spec or test directories together.  Even if you might believe that code bulk is bad, I think that it&amp;#8217;s reasonable to think of the code bulk in the implementation to be like &amp;#8216;bad cholesterol&amp;#8217;, and test-code which verifies that implementation as &amp;#8216;good cholesterol.&amp;#8217;  Most of you are probably too young to be concerned about it yet, but my doctors tell me that a high &lt;span class="caps"&gt;HDL&lt;/span&gt;/LDL ratio is more important than an absolute &lt;span class="caps"&gt;HDL&lt;/span&gt;+LDL.  The theory at least is that the &lt;span class="caps"&gt;HDL&lt;/span&gt; helps sweep the &lt;span class="caps"&gt;LDL&lt;/span&gt; out of the vessels, kind of like a good test suite keeps code under control.&lt;/p&gt;


	&lt;p&gt;Here are the numbers I get running sloccount on the latest RSpec and test/unit gems:&lt;/p&gt;


	&lt;table style="border:1px solid black; align:right;"&gt;
		&lt;tr&gt;
			&lt;th&gt;Framework &lt;/th&gt;
			&lt;th&gt;lib &lt;/th&gt;
			&lt;th&gt;spec/test&lt;/th&gt;
			&lt;th&gt;test/code ratio &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Rspec &lt;/td&gt;
			&lt;td&gt; 5473 &lt;/td&gt;
			&lt;td&gt;10108  &lt;/td&gt;
			&lt;td&gt; 1.8 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Test::Spec &lt;/td&gt;
			&lt;td&gt; 275 &lt;/td&gt;
			&lt;td&gt; 879 &lt;/td&gt;
			&lt;td&gt; 3.2 &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;So at first blush it looks bad for RSpec, Test::Spec even tests itself more thoroughly!&lt;/p&gt;


	&lt;p&gt;The real problem with Rob&amp;#8217;s post is that he&amp;#8217;s comparing Apple seeds with Apples.  Of course Test::Spec is considerably smaller than RSpec, it&amp;#8217;s a bump on Test::Unit to add the new assertion style.  So we need to at least add Test::Unit&amp;#8217;s numbers&lt;/p&gt;


	&lt;table style="border:1px solid black; align:right;"&gt;
		&lt;tr&gt;
			&lt;th&gt;Framework &lt;/th&gt;
			&lt;th&gt;lib &lt;/th&gt;
			&lt;th&gt;spec/test&lt;/th&gt;
			&lt;th&gt;test/code ratio &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Test:Unit &lt;/td&gt;
			&lt;td&gt; 2741 &lt;/td&gt;
			&lt;td&gt; 0 &lt;/td&gt;
			&lt;td&gt; 0 &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;Now I&amp;#8217;m sure that Nathaniel &amp;#8220;ate his own dog food&amp;#8221; when he developed Test::Unit, and Ryan is continuing to dine on it, now that he&amp;#8217;s taken over its maintenance, but that dog food apparently doesn&amp;#8217;t leave home.  Now if we look at the combination of Test::Unit and Test::Spec the comparison looks like this:&lt;/p&gt;


	&lt;table style="border:1px solid black; align:right;"&gt;
		&lt;tr&gt;
			&lt;th&gt;Framework &lt;/th&gt;
			&lt;th&gt;lib &lt;/th&gt;
			&lt;th&gt;spec/test&lt;/th&gt;
			&lt;th&gt;test/code ratio &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Rspec &lt;/td&gt;
			&lt;td&gt; 5473 &lt;/td&gt;
			&lt;td&gt;10108  &lt;/td&gt;
			&lt;td&gt; 1.8 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; TU+TS &lt;/td&gt;
			&lt;td&gt; 2713 &lt;/td&gt;
			&lt;td&gt; 879 &lt;/td&gt;
			&lt;td&gt; 0.3 &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;So RSpec looks a little better, particularly when it comes to eating it&amp;#8217;s own dog food.&lt;/p&gt;


	&lt;p&gt;But, as that Billy Mays guy on the Infomercials is wont to say, &amp;#8220;Wait! There&amp;#8217;s more!&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;RSpec also includes a built-in mocking framework, now with the &amp;#8216;traditional&amp;#8217; choice you need to throw in your choice of mock framework, here&amp;#8217;s are the stats for Flexmock and Mocha&lt;/p&gt;


	&lt;table style="border:1px solid black; align:right;"&gt;
		&lt;tr&gt;
			&lt;th&gt;Framework &lt;/th&gt;
			&lt;th&gt;lib &lt;/th&gt;
			&lt;th&gt;spec/test&lt;/th&gt;
			&lt;th&gt;test/code ratio &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Flexmock &lt;/td&gt;
			&lt;td&gt; 1034  &lt;/td&gt;
			&lt;td&gt; 2743 &lt;/td&gt;
			&lt;td&gt; 2.6 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Mocha    &lt;/td&gt;
			&lt;td&gt; 1218  &lt;/td&gt;
			&lt;td&gt; 3622 &lt;/td&gt;
			&lt;td&gt; 2.8 &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;So now we&amp;#8217;ve got two sub-variants to look at:&lt;/p&gt;


	&lt;table style="border:1px solid black; align:right;"&gt;
		&lt;tr&gt;
			&lt;th&gt;Framework &lt;/th&gt;
			&lt;th&gt;lib &lt;/th&gt;
			&lt;th&gt;spec/test&lt;/th&gt;
			&lt;th&gt;test/code ratio &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; Rspec &lt;/td&gt;
			&lt;td&gt; 5473 &lt;/td&gt;
			&lt;td&gt;10108  &lt;/td&gt;
			&lt;td&gt; 1.8 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; TU+TS+FM &lt;/td&gt;
			&lt;td&gt; 3747 &lt;/td&gt;
			&lt;td&gt; 3622 &lt;/td&gt;
			&lt;td&gt; 1.0 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; TU+TS+Mocha &lt;/td&gt;
			&lt;td&gt; 3931 &lt;/td&gt;
			&lt;td&gt;  3931 &lt;/td&gt;
			&lt;td&gt; 1.1 &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;Now you might say that RSpec still is 40% larger than even the larger of the two competing combinations, but this is also ignoring the fact that RSpec also includes RBehave which is another higher level integration/acceptance testing framework.&lt;/p&gt;


	&lt;p&gt;So in retrospect, I&amp;#8217;d humbly submit that code bulk isn&amp;#8217;t such a good comparison criteria in this case.&lt;/p&gt;


	&lt;p&gt;So whatever your test framework &amp;#8216;belief system&amp;#8217; do as you feel best, but do unto others!&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;d still like to hear more about why people think that RSpec is &amp;#8220;too magic&amp;#8221; though.&lt;/p&gt;


	&lt;p&gt;By the way on the subject of lying statistics.  I&amp;#8217;m sure that most of us have by now seen &lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java&amp;#38;relative=1"&gt;this chart of Ruby job prospects.&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Which looks like, and is, &lt;span class="caps"&gt;GREAT&lt;/span&gt; news for Rubyists, but how many have seen &lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java"&gt;this from the same source.&lt;/a&gt; It&amp;#8217;s the same data, just looked at through a different lens.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m still not looking for Java work though!&lt;/p&gt;</description>
      <pubDate>Tue, 29 Jan 2008 16:24:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:29b762a2-2d17-453e-9346-48acb81d03d2</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2008/01/29/why-i-dont-mind-using-rspec-in-fact-ive-come-to-love-it</link>
      <category>ruby</category>
      <category>rails</category>
      <category>tdd</category>
      <category>bdd</category>
      <category>Rspec</category>
      <category>TestUnit</category>
      <category>TestSpec</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/485</trackback:ping>
    </item>
  </channel>
</rss>
