<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Nick Sieger: Tag rspec</title>
  <id>tag:blog.nicksieger.com,2005:Typo</id>
  <generator uri="http://www.typosphere.org" version="4.0">Typo</generator>
  <link href="http://blog.nicksieger.com/xml/atom10/tag/rspec/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.nicksieger.com/articles/tag/rspec?tag=rspec" rel="alternate" type="text/html"/>
  <updated>2007-08-31T16:45:13+00:00</updated>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:21755a2d-0ffa-4f0c-be7d-a2e2e01d99b4</id>
    <published>2007-01-02T05:32:00+00:00</published>
    <updated>2007-08-31T16:45:13+00:00</updated>
    <title>Customizing RSpec</title>
    <link href="http://blog.nicksieger.com/articles/2007/01/02/customizing-rspec" rel="alternate" type="text/html"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <category term="ruby" scheme="http://blog.nicksieger.com/articles/tag/ruby"/>
    <category term="metaprogramming" scheme="http://blog.nicksieger.com/articles/tag/metaprogramming"/>
    <content type="html">&lt;p&gt;&lt;em&gt;Update/Disclaimer: I refer to parts of RSpec that are not blessed as an extension API.  Redefining &lt;code&gt;before_context_eval&lt;/code&gt; and using the &lt;code&gt;@context_eval_module&lt;/code&gt; variable directly may change in the future.  I&amp;#8217;ll keep this article updated to coincide with the changes.  For now, these techniques should work fine with RSpec versions up to 0.7.5.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RSpec seems to be getting more attention lately as a viable, nay, &lt;em&gt;preferred&lt;/em&gt;, alternative to Test::Unit.  It&amp;#8217;s possible that it&amp;#8217;s just my personal feed-reader-echo-chamber, but consider this:  &lt;a href="http://blog.fallingsnow.net/rubinius/"&gt;Rubinius&lt;/a&gt; has started using RSpec alongside Test::Unit as an another way to test the alternate Ruby implementation.  They&amp;#8217;re even in the midst of building some snazzy extensions to allow the same specs to be run under a Ruby implementation of your choice.  (Perhaps this will point the way to a new round of executable specs to accompany the &lt;a href="http://www.headius.com/rubyspec/index.php/Main_Page"&gt;fledgling community spec&lt;/a&gt;?  Let&amp;#8217;s wait and see how they do and leave that topic for another day.)&lt;/p&gt;

&lt;p&gt;But extending and customizing RSpec to add a DSL on top of RSpec&amp;#8217;s &lt;code&gt;context/specify&lt;/code&gt; framework doesn&amp;#8217;t have to be the realm of experts.  Here are some templates for how you can DRY up your specs by adding your own helper methods in such a way that they will be available to all your specs.  But first, a little background.&lt;/p&gt;

&lt;h3&gt;Spec Helper&lt;/h3&gt;

&lt;p&gt;Most usages of RSpec that I&amp;#8217;ve seen in the wild use a &amp;#8220;spec helper&amp;#8221; (&lt;code&gt;spec_helper.rb&lt;/code&gt;).  This file, following the pattern of Rails&amp;#8217; &lt;code&gt;test_helper.rb&lt;/code&gt;, minimally contains require statements to pull in the RSpec code and any supporting code for running specs.  By requiring the spec helper via a path relative to your spec (usually with &lt;code&gt;require File.dirname(__FILE__) + '/spec_helper'&lt;/code&gt; or similar), it also allows you the convenience of running your specs one at a time from anywhere (say, by launching from your editor) or with &lt;code&gt;rake&lt;/code&gt; or &lt;code&gt;spec&lt;/code&gt;.  This file is where your shared helper methods will go, and where they&amp;#8217;ll get registered to be pulled into the contexts.&lt;/p&gt;

&lt;h3&gt;What Context in &lt;code&gt;context&lt;/code&gt;?&lt;/h3&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;context&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A new stack&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="comment"&gt;# &amp;lt;== What is the value of &amp;quot;self&amp;quot; here?&lt;/span&gt;
  &lt;span class="ident"&gt;specify&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should be empty&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="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How do those contexts work anyway?  The &lt;code&gt;context&lt;/code&gt; method that defines a context in which specs can be defined and run takes a block to define the individual specs, but what can really go in that block?&lt;/p&gt;

&lt;p&gt;It turns out that RSpec jumps through metaprogramming hoops (using &lt;code&gt;class_eval&lt;/code&gt;) to make the block behave like a class definition.  This means you can do things like put method definitions inside your context:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;context&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A new stack&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="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;a_new_stack&lt;/span&gt;
    &lt;span class="constant"&gt;Stack&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;span class="ident"&gt;specify&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should be empty&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;a_new_stack&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_be_empty&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which is nice, but the reason we&amp;#8217;re here is to hide that away in &lt;code&gt;spec_helper.rb&lt;/code&gt;.  So, to get back to the point of the comment in the first example above, the &lt;code&gt;self&lt;/code&gt; inside the context block is an anonymous &lt;code&gt;Module&lt;/code&gt; object.  It&amp;#8217;s constructed in the &lt;code&gt;initialize&lt;/code&gt; method of a &lt;code&gt;Context&lt;/code&gt; (condensed from &lt;code&gt;spec/runner/context.rb&lt;/code&gt; in the RSpec codebase):&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Spec::Runner::Context&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;context_block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;name&lt;/span&gt;

    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;extend&lt;/span&gt; &lt;span class="constant"&gt;ContextEval&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;ModuleMethods&lt;/span&gt;
    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;ContextEval&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;InstanceMethods&lt;/span&gt;
    &lt;span class="ident"&gt;before_context_eval&lt;/span&gt;
    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;class_eval&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;context_block&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;def &lt;/span&gt;&lt;span class="method"&gt;before_context_eval&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Take note of that empty &lt;code&gt;before_context_eval&lt;/code&gt; method and the fact that it&amp;#8217;s invoked during context initialization; that&amp;#8217;s where we can plug in our custom extensions.)&lt;/p&gt;

&lt;p&gt;The object held by the &lt;code&gt;@context_eval_module&lt;/code&gt; instance variable is being augmented in two ways: extension and inclusion.  The object is &lt;em&gt;extended&lt;/em&gt; with the &lt;code&gt;ContextEval::ModuleMethods&lt;/code&gt; module; these methods are being added to the object&amp;#8217;s singleton class.  This has the effect of making these methods visible within the &lt;code&gt;context&lt;/code&gt; block, functioning similar to &amp;#8220;class&amp;#8221; methods.&lt;/p&gt;

&lt;p&gt;The object also has the &lt;code&gt;ContextEval::InstanceMethods&lt;/code&gt; module &lt;em&gt;included&lt;/em&gt;.  This has the effect of adding these as instance methods, making them visible from within &lt;code&gt;specify&lt;/code&gt; blocks, which are made to behave like instance methods on the same object.&lt;/p&gt;

&lt;h3&gt;Putting it together&lt;/h3&gt;

&lt;table style="text-align: left;" summary=""&gt;
  &lt;thead&gt;
    &lt;th&gt;Technique&lt;/th&gt;
    &lt;th&gt;Visibility&lt;/th&gt;
    &lt;th&gt;Use&lt;/th&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;@context_eval_module.extend&lt;/td&gt;&lt;td&gt;Context block&lt;/td&gt;&lt;td&gt;Custom setup, shared state declaration&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;@context_eval_module.include&lt;/td&gt;&lt;td&gt;Specify block&lt;/td&gt;&lt;td&gt;Shared actions/functions, stub/expectation modification, encapsulate instance variables&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4&gt;Adding specialized setup methods&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;spec_helper.rb&lt;/code&gt; snippet:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;SharedSetupMethods&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;setup_new_stack&lt;/span&gt;
    &lt;span class="ident"&gt;setup&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="attribute"&gt;@stack&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Stack&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;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Spec::Runner::Context&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;before_context_eval&lt;/span&gt;
    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;extend&lt;/span&gt; &lt;span class="constant"&gt;SharedSetupMethods&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example spec:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;context&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A new stack&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;setup_new_stack&lt;/span&gt;

  &lt;span class="ident"&gt;specify&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should be empty&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="attribute"&gt;@stack&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_be_empty&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Adding shared accessors&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;spec_helper.rb&lt;/code&gt; snippet:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;StackMethods&lt;/span&gt;
  &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:stack&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;push_an_object&lt;/span&gt;
    &lt;span class="ident"&gt;stack&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;mock&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;some object&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;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Spec::Runner::Context&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;before_context_eval&lt;/span&gt;
    &lt;span class="attribute"&gt;@context_eval_module&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;StackMethods&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example spec:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;context&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A stack with an object pushed&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;setup&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="attribute"&gt;@stack&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Stack&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;span class="ident"&gt;specify&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should not be empty&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;stack&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_be_empty&lt;/span&gt;
    &lt;span class="ident"&gt;push_an_object&lt;/span&gt;
    &lt;span class="ident"&gt;stack&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_not_be_empty&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The examples are simple, but hopefully illustrate the techniques.  For an example of some code that&amp;#8217;s actually useful, check out my sample &lt;a href="http://svn.caldersphere.net/svn/main/rspec_selenium_rc/trunk/"&gt;RSpec Selenium RC integration project&lt;/a&gt;, in particular the &lt;a href="http://svn.caldersphere.net/svn/main/rspec_selenium_rc/trunk/lib/spec_helper.rb"&gt;spec helper&lt;/a&gt; and the &lt;a href="http://svn.caldersphere.net/svn/main/rspec_selenium_rc/trunk/spec/example_spec.rb"&gt;example spec&lt;/a&gt;.  (More on this in the future if it proves useful, but for now if you check it out and run &lt;code&gt;rake&lt;/code&gt; on it, it should launch &lt;a href="http://www.openqa.org/selenium-rc/"&gt;Selenium RC&lt;/a&gt; and run the example spec in a Firefox browser.)&lt;/p&gt;

&lt;p&gt;By mixing and matching these techniques, you can layer a mini-DSL on top of RSpec and achieve DRY-er and even more readable and intention-revealing specs.  Let me know if you&amp;#8217;re able to find uses for these tips!&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:8396524a-7e00-4aad-8727-a5a0b3ec7ef3</id>
    <published>2006-11-15T15:46:00+00:00</published>
    <updated>2007-08-31T16:57:59+00:00</updated>
    <title>RSpec Autotest now a Rails Plugin</title>
    <link href="http://blog.nicksieger.com/articles/2006/11/15/rspec-autotest-now-a-rails-plugin" rel="alternate" type="text/html"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <category term="rails" scheme="http://blog.nicksieger.com/articles/tag/rails"/>
    <category term="plugin" scheme="http://blog.nicksieger.com/articles/tag/plugin"/>
    <content type="html">&lt;p&gt;Inspired by a &lt;a href="http://rubyforge.org/pipermail/rspec-devel/2006-November/001219.html"&gt;posting on the RSpec list&lt;/a&gt; and recent &lt;a href="http://blog.nicksieger.com/articles/2006/09/13/auto-rspec#comment-143"&gt;comments stating that my Auto RSpec hack wasn&amp;#8217;t working&lt;/a&gt;, I&amp;#8217;ve bitten the bullet and upgraded to &lt;a href="http://rspec.rubyforge.org/upgrade.html"&gt;RSpec 0.7.2&lt;/a&gt;, and made &lt;code&gt;rspec_autotest&lt;/code&gt; &lt;a href="http://svn.caldersphere.net/svn/main/plugins/rspec_autotest"&gt;a plugin&lt;/a&gt; in the process.  So, herewith are the necessary incantations to auto-rspec your project.  If you&amp;#8217;ve tried my hack already, please remove any bits you previously had installed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install RSpec on Rails, following the &lt;a href="http://rspec.rubyforge.org/documentation/rails/install.html"&gt;original instructions&lt;/a&gt;.  As of RSpec 0.7.3, the specific version of ZenTest is no longer required.  Also, diff-lcs is required to show unified diff output on &lt;code&gt;should ==&lt;/code&gt; failures.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;gem install zentest -v 3.4.1
gem install diff-lcs
gem install rspec
script/plugin install svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_2/vendor/rspec_on_rails/vendor/plugins/rspec&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;rspec_autotest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;script/plugin install http://svn.caldersphere.net/svn/main/plugins/rspec_autotest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Start autotest&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rake spec:autotest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Please let me know if you experience any problems!&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:52bf2e58-ea0e-4473-bad5-c7b42775bfee</id>
    <published>2006-09-13T20:35:00+00:00</published>
    <updated>2007-08-31T17:25:45+00:00</updated>
    <title>Auto RSpec</title>
    <link href="http://blog.nicksieger.com/articles/2006/09/13/auto-rspec" rel="alternate" type="text/html"/>
    <category term="testing" scheme="http://blog.nicksieger.com/articles/category/testing" label="testing"/>
    <category term="ruby" scheme="http://blog.nicksieger.com/articles/category/ruby" label="ruby"/>
    <category term="rails" scheme="http://blog.nicksieger.com/articles/category/rails" label="rails"/>
    <category term="ruby" scheme="http://blog.nicksieger.com/articles/tag/ruby"/>
    <category term="autotest" scheme="http://blog.nicksieger.com/articles/tag/autotest"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <category term="testing" scheme="http://blog.nicksieger.com/articles/tag/testing"/>
    <content type="html">&lt;p&gt;&lt;em&gt;Update: (2 months later) If you&amp;#8217;re reading this, you&amp;#8217;re probably interested in &lt;a href="/articles/2006/11/15/rspec-autotest-now-a-rails-plugin"&gt;my Rails plugin for this&lt;/a&gt; instead.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hot off the presses, after a few hours of hacking and tweaking, may I present Auto+RSpec, otherwise known as The Mashup of &lt;a href="http://rspec.rubyforge.org/tools/rails.html"&gt;RSpec on Rails&lt;/a&gt; and &lt;a href="http://www.zenspider.com/ZSS/Products/ZenTest/"&gt;autotest&lt;/a&gt;.  This is not an official release of any sort, but &amp;#8220;may work for you.&amp;#8221;  It&amp;#8217;s not a clean hack, as it exposes some areas for autotest to grow if the maintainers decide to open it up to alternatives to Test::Unit.  After spending a little time looking at the autotest code, I think it would be nice to allow hooks for autotest plugins to define project conventions (i.e., &lt;code&gt;@exceptions&lt;/code&gt; and the &lt;code&gt;#tests_for_file&lt;/code&gt; method) as well as a result parsing API.&lt;/p&gt;

&lt;p&gt;For now, if you&amp;#8217;re an RSpec on Rails user, you can try this out as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="http://www.zenspider.com/ZSS/Products/ZenTest/"&gt;ZenTest&lt;/a&gt; if you haven&amp;#8217;t already: &lt;code&gt;sudo gem install ZenTest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="http://svn.caldersphere.net/svn/main/rspec_autotest/trunk/lib/rspec_autotest.rb"&gt;rspec_autotest.rb&lt;/a&gt; and put in your &lt;code&gt;vendor/plugins/rspec/lib&lt;/code&gt; directory (you did say you&amp;#8217;re using RSpec on Rails didn&amp;#8217;t you?)&lt;/li&gt;
&lt;li&gt;Download &lt;a href="http://svn.caldersphere.net/svn/main/rspec_autotest/trunk/tasks/rspec_autotest.rake"&gt;rspec_autotest.rake&lt;/a&gt; and put in your &lt;code&gt;lib/tasks&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Start &lt;code&gt;autotest&lt;/code&gt; with rake by typing &lt;code&gt;rake spec:autotest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Note: if you&amp;#8217;re using RSpec 0.6, you might have better success with &lt;a href="http://svn.caldersphere.net/svn/main/rspec_autotest/tags/rspec-0.6.0"&gt;the files located here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next steps for this will be to work out whether this code should live in RSpec on Rails or autotest, or some combination of those.&lt;/p&gt;

&lt;p&gt;Now, spec&amp;#8217;ers, be off in search of that &lt;strong&gt;Red/Green/Refactor&lt;/strong&gt; rhythm of which sage agilists speak!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus tip&lt;/strong&gt;: add the following code to your &lt;code&gt;.autotest&lt;/code&gt; file to run &lt;code&gt;spec&lt;/code&gt; with &lt;code&gt;rcov&lt;/code&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="constant"&gt;Autotest&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_hook&lt;/span&gt; &lt;span class="symbol"&gt;:initialize&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;at&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="comment"&gt;# run spec with rcov&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;at&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;respond_to?&lt;/span&gt; &lt;span class="symbol"&gt;:spec_command&lt;/span&gt;
      &lt;span class="ident"&gt;at&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;spec_command&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;%{&lt;/span&gt;&lt;span class="string"&gt;rcov --exclude &amp;quot;lib/spec/.*&amp;quot; -Ilib --rails &amp;quot;/usr/lib/ruby/gems/1.8/gems/rspec-0.6.0/bin/spec&amp;quot; -- --diff&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:b67283f4-b1e1-41e0-bb1a-794dd7135564</id>
    <published>2006-12-01T18:56:00+00:00</published>
    <updated>2007-08-31T17:32:27+00:00</updated>
    <title>RSpec, JRuby, Mocking, and Multiple Interfaces</title>
    <link href="http://blog.nicksieger.com/articles/2006/12/01/rspec-jruby-mocking-and-multiple-interfaces" rel="alternate" type="text/html"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <category term="jruby" scheme="http://blog.nicksieger.com/articles/tag/jruby"/>
    <category term="mockobjects" scheme="http://blog.nicksieger.com/articles/tag/mockobjects"/>
    <content type="html">&lt;p&gt;The prospect of doing &lt;a href="http://behaviour-driven.org/"&gt;behavior-driven development&lt;/a&gt; in Java has just taken a step closer with the news of &lt;a href="http://www.infoq.com/news/2006/11/RSpecOnJRuby"&gt;RSpec running on JRuby&lt;/a&gt;. This is already a big step that will have an impact on Ruby and Java programmers alike in &lt;a href="http://on-ruby.blogspot.com/2006/12/jruby-and-rspec-leftovers.html"&gt;a number of ways&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, it could be even better. RSpec has a nice, intuitive mocking API, which will unfortunately, at the present time, be useless when working with java objects.  It would be awesome to try to get it to work, though.  Some possibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Map to &lt;a href="http://www.jmock.org/"&gt;JMock&lt;/a&gt; and use JMock under the hood.  Not a very attractive option for a number of reasons, but mainly because add-on bridging layers are complex and should be avoided.&lt;/li&gt;
&lt;li&gt;Improve ability for JRuby to implement any number of Java interfaces dynamically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This second option is something &lt;a href="http://headius.blogspot.com/"&gt;Charlie&lt;/a&gt;, &lt;a href="http://www.bloglines.com/blog/ThomasEEnebo"&gt;Tom&lt;/a&gt; and I talked about on Tuesday night, that could have a much broader impact on Java integration in JRuby.&lt;/p&gt;

&lt;p&gt;Consider this spec. It&amp;#8217;s trivial, but bear with me.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;context&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A TaskRunner&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;setup&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="attribute"&gt;@task&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;mock&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Runnable&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@task_runner&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;TaskRunner&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="attribute"&gt;@task&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;specify&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;runs a task when executed&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="attribute"&gt;@task&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:run&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@task_runner&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This spec might be satisfied by the following Java code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;public class TaskRunner {
  private Runnable task;
  public TaskRunner(Runnable r) {
    this.task = r;
  }

  public void execute() {
    task.run();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice how I defined the &lt;code&gt;@task&lt;/code&gt; in the spec above.  This is the normal way of &lt;a href="http://rspec.rubyforge.org/documentation/mocks/mocks.html"&gt;mocking in RSpec&lt;/a&gt;, and the example illustrates how I think JRuby should handle interfaces in Java: by duck-typing them.&lt;/p&gt;

&lt;p&gt;Basically, the RSpec mock should act like a Java Runnable because I&amp;#8217;ve defined a &lt;code&gt;run&lt;/code&gt; method on it (in this case implicitly with &lt;code&gt;@task.should_receive(:run)&lt;/code&gt;).  JRuby could wrap a dynamic invocation proxy around &lt;strong&gt;any&lt;/strong&gt; Ruby object just before passing it into a Java method invocation.  Without doing any type- or method-checking up front.  Just define the proxy as implementing the interface required by the Java method signature, and let the JRuby runtime do its thing, and attempt to resolve methods as they&amp;#8217;re invoked.  Possibly falling back to method_missing, even!&lt;/p&gt;

&lt;p&gt;Note that this would also make moot the &lt;a href="http://headius.blogspot.com/2006/09/interface-implementation-syntax-and.html"&gt;multiple interface syntax discussion&lt;/a&gt;, because you&amp;#8217;d never have to declare an object in JRuby as implementing any particular interface.  Just define the appropriately named methods with the proper arity, and you&amp;#8217;re done.  Maybe you don&amp;#8217;t even need to declare all of them, if they never get called for your usage!  This is the Ruby Way, and would be a completely natural extension to the way Java objects are manipulated in JRuby today, not to mention extremely concise and powerful.&lt;/p&gt;

&lt;p&gt;This would also allow RSpec mocking to &lt;em&gt;just work&lt;/em&gt;, at least for Java interface types, which would be way cool.&lt;/p&gt;

&lt;p&gt;Charlie has a Swing demo that he frequently gives when &lt;a href="http://tech.puredanger.com/2006/11/07/jruby/"&gt;talking about JRuby&lt;/a&gt;.  Under the new proposal, it would look more like this:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;java&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;javax&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;swing&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;JFrame&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;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Hello&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;setSize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;200&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;200&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;show&lt;/span&gt;

&lt;span class="ident"&gt;button&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;javax&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;swing&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;JButton&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;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;OK!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;button&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;show&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;actionPerformed&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;text&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;Pressed!&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;button&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;addActionListener&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With luck, this approach will be coming to JRuby very soon.&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:ea568e8e-e6f4-4fb7-80df-8da5f50065b9</id>
    <published>2007-01-30T02:16:00+00:00</published>
    <updated>2007-08-31T18:00:07+00:00</updated>
    <title>RSpec Autotest for Standalone Projects</title>
    <link href="http://blog.nicksieger.com/articles/2007/01/30/rspec-autotest-for-standalone-projects" rel="alternate" type="text/html"/>
    <category term="ruby" scheme="http://blog.nicksieger.com/articles/tag/ruby"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <category term="autotest" scheme="http://blog.nicksieger.com/articles/tag/autotest"/>
    <content type="html">&lt;p&gt;I know there has been some demand out there for a version of my &lt;a href="/articles/2006/11/15/rspec-autotest-now-a-rails-plugin"&gt;RSpec Autotest Rails plugin&lt;/a&gt; that works with standalone (non-Rails) projects, so I finally caved and coded it up.  I really hope this does finally get accepted as &lt;a href="https://rubyforge.org/tracker/?func=detail&amp;amp;aid=6732&amp;amp;group_id=419&amp;amp;atid=1680"&gt;a patch to ZenTest&lt;/a&gt; (nudge, nudge), but until it gets a more standard release, do try it out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure you have ZenTest installed (&lt;code&gt;gem install ZenTest&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://svn.caldersphere.net/svn/main/rspec_autotest/trunk/lib/rspec_autotest.rb"&gt;Download the rspec_autotest.rb file here&lt;/a&gt; and put it in the &lt;code&gt;spec&lt;/code&gt; directory of your project.&lt;/li&gt;
&lt;li&gt;Add this snippet of code into your &lt;code&gt;Rakefile&lt;/code&gt;, and &lt;code&gt;rake spec:autotest&lt;/code&gt; as usual.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;namespace&lt;/span&gt; &lt;span class="symbol"&gt;:spec&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="symbol"&gt;:autotest&lt;/span&gt; &lt;span class="keyword"&gt;do&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;./spec/rspec_autotest&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="constant"&gt;RspecAutotest&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once again, happy spec&amp;#8217;ing, and let me know of any issues you have with it.&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:48613cce-c252-4be0-a12e-923eb239c87a</id>
    <published>2007-11-04T16:26:00+00:00</published>
    <updated>2007-11-05T16:52:49+00:00</updated>
    <title>RubyConf Day 3: Behaviour-Driven Development with RSpec</title>
    <link href="http://blog.nicksieger.com/articles/2007/11/04/rubyconf-day-3-behaviour-driven-development-with-rspec" rel="alternate" type="text/html"/>
    <category term="rubyconf" scheme="http://blog.nicksieger.com/articles/tag/rubyconf"/>
    <category term="rubyconf2007" scheme="http://blog.nicksieger.com/articles/tag/rubyconf2007"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <content type="html">&lt;h2&gt;David Chelimsky and Dave Astels: RSpec&lt;/h2&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;TestDriverDevelopment&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;is an incremental process&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;drives the implementation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;results in an exhaustive test suite&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="comment"&gt;# but also...&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should focus on design&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should focus on documentation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should focus on behaviour&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;class &lt;/span&gt;&lt;span class="class"&gt;BehaviourDrivenDevelopment&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;TestDrivenDevelopment&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;FocusOnDesign&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;FocusOnDocumentation&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;FocusOnBehavior&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When doing test-driven development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write your intent first. The smallest test you can that fails.&lt;/li&gt;
&lt;li&gt;Next, write the implementation. The simplest thing that could possibly work.&lt;/li&gt;
&lt;li&gt;Even though you may be tempted to think about additional edge cases, multiple requirements, etc., you should try to be disciplined and focus only on the immediate tests. Only after you&amp;#8217;ve made one test fail, then pass, can you continue on to other tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;RSpec history&lt;/h3&gt;

&lt;p&gt;Initially BDD was just a discussion among Aslak Hellesoy and Dan North in the ThoughtWorks London office. Dave Astels joined the conversation with a blog post stating that he thought these ideas could be easily implemented in Smalltalk or Ruby. Steven Baker jumped in with an initial implementation, and released RSpec 0.1. Later in 2006, maintenance was handed over to David Chelimsky. RSpec has evolved through a dog-fooding phase up to the present 1.0 product.&lt;/p&gt;

&lt;p&gt;BDD is no longer just about &amp;#8220;should instead of assert&amp;#8221;, it&amp;#8217;s evolving into a process. Emphasizing central concepts from extreme programming and domain-driven design, it&amp;#8217;s moving toward focusing on customer stories and acceptance testing. It&amp;#8217;s outside-in, starting at high levels of detail, rather than low-level like RSpec or Test::Unit.&lt;/p&gt;

&lt;h3&gt;Story Runner&lt;/h3&gt;

&lt;p&gt;Story Runner is a new feature intended for RSpec 1.1. Each story is supposed to capture a customer requirement in the following general template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;As a (role) ... I want to (some function) ... so that (some business value).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses a &amp;#8220;Scenario &amp;#8230; Given &amp;#8230; When &amp;#8230; Then &amp;#8230;&amp;#8221; format to express the high level stories. Scenarios are a series of given items, steps, and behaviour validations. Once the basic steps are established, they can be re-used. David even demonstrated a preview of an in-browser story runner that would allow the customer to play with the implementation and create new scenarios.&lt;/p&gt;

&lt;h3&gt;Pending&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Pending&lt;/em&gt; is a nice way to mark specs as &amp;#8220;in-progress&amp;#8221;. You can either omit a block for your spec, or use &lt;code&gt;pending&lt;/code&gt; inside the block to leave a placeholder to come back to.&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;Pending&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;doesn't need a block to be pending&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;could also be specified inside the block&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;pending&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;TODO&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="ident"&gt;this&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_not&lt;/span&gt; &lt;span class="ident"&gt;be_a_failure&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;could also use a block with pending, and you will be notified when it starts to succeed&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;pending&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;TODO&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;this&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_not&lt;/span&gt; &lt;span class="ident"&gt;be_a_failure&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;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Behaviour-Driven Development in Ruby with RSpec is a new book David and Aslak are working on, due out early next year.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: &lt;a href="http://blog.davidchelimsky.net/articles/2007/11/05/rubyconf-slides"&gt;David has posted his slides&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>Nick Sieger</name>
    </author>
    <id>urn:uuid:ef52ee82-3d63-4899-9170-5f26293291fc</id>
    <published>2008-02-08T15:13:16+00:00</published>
    <updated>2008-02-08T15:13:16+00:00</updated>
    <title>Screencast: RSpec and NetBeans</title>
    <link href="http://blog.nicksieger.com/articles/2008/02/08/screencast-rspec-and-netbeans" rel="alternate" type="text/html"/>
    <category term="ruby" scheme="http://blog.nicksieger.com/articles/tag/ruby"/>
    <category term="jruby" scheme="http://blog.nicksieger.com/articles/tag/jruby"/>
    <category term="netbeans" scheme="http://blog.nicksieger.com/articles/tag/netbeans"/>
    <category term="rspec" scheme="http://blog.nicksieger.com/articles/tag/rspec"/>
    <content type="html">&lt;p&gt;A &lt;a href="http://www.netbeans.tv/screencasts/Nick-Sieger-Uses-RSpec-with-the-NetBeans-Ruby-Support-305/"&gt;new screen cast is up&lt;/a&gt; with yours truly showing off &lt;a href="http://wiki.netbeans.org/RubyTesting"&gt;NetBeans&amp;#8217; RSpec support&lt;/a&gt;. Additionally, I tried to make it interesting to a wider audience by really showcasing RSpec&amp;#8217;s strengths, and trying to capture some of the &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test-driven development - Wikipedia, the free encyclopedia"&gt;red-green-refactor&lt;/a&gt; rhythm. NetBeans does work really well for this, but in my mind, the star of the show is &lt;a href="http://rspec.info/" title="RSpec-1.1.3: Overview"&gt;RSpec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m pleased with how it turned out considering I hadn&amp;#8217;t done this sort of thing before. Special thanks to Cindy Church for putting it all together, including all the production: setup, recording, editing, even the music!&lt;/p&gt;

&lt;p&gt;A &lt;a href="http://mediacast.sun.com/users/cindo/media/NickSiegerRSpec.mov"&gt;QuickTime movie&lt;/a&gt; version is available as well. Check it out and let me know what you think.&lt;/p&gt;</content>
  </entry>
</feed>
