[rspec-users] Specification Reuse to avoid Combinatorial Explosions

Brian Takita brian.takita at gmail.com
Tue Nov 21 04:52:18 EST 2006


Hello,

While reading Dan North's BDD tutorial <http://dannorth.net/introducing-bdd>,
I tried to implement his ATM example as spec stubs.
When I first implemented it creating a context for each of his scenarios, I
noticed that there is duplication and a combinatorial explosion of the
specs.

I attached the full files to this email. For brevity, I will use scenario 1
in the body of this email. For the purpose of this exercise, one should
imagine that each specification is at least 5 lines.

Here is how I implemented scenario 1:

context %{A Withdrawal where an Account is in credit
        AND the card is valid
        AND the dispenser contains cash
        AND the customer requests cash} do

  specify "should debit the account" do
  end
  specify "should dispense cash" do
  end
  specify "should return the card" do
  end
end

That got me experimenting on reusing specifications by using a module to
create the specs. This is in customer_withdraws_cash_spec.rb:

module CustomerWithdrawsCashSpec
  def should_debit_the_account
    specify "should debit the account" do
    end
  end
  ...
end
...
context %{A Withdrawal where an Account is in credit
        AND the card is valid
        AND the dispenser contains cash
        AND the customer requests cash} do

  extend CustomerWithdrawsCashSpec
  should_debit_the_account
  should_dispense_cash
  should_return_the_card
end

This is currently possible with rspec 0.7.2.
Whats interesting about putting all of the specifications into a module is
that you can reduce the context to a few lines.
This makes each context (scenario readable) making it more feasible to have
multiple contexts in a single file such as this group of scenarios
represented as contexts.

I also played with a more DSL-like syntax for this, which does not work for
rspec 0.7.2. This is in customer_withdraws_cash_alternative_spec.rb::

CustomerWithdrawsCashSpec = context_module do
  specify "should debit the account" do
  end
  ...
end

context %{A Withdrawal where an Account is in credit
        AND the card is valid
        AND the dispenser contains cash
        AND the customer requests cash} do

  extend CustomerWithdrawsCashSpec
  specify "should debit the account"
  specify "should dispense cash"
  specify "should return the card"
end

As well as:

context %{A Withdrawal where an Account is in credit
        AND the card is valid
        AND the dispenser contains cash
        AND the customer requests cash} do

  specify "should debit the account", CustomerWithdrawsCashSpec
  specify "should dispense cash", CustomerWithdrawsCashSpec
  specify "should return the card", CustomerWithdrawsCashSpec
end

Or just keep the underscore syntax:

context %{A Withdrawal where an Account is in credit
        AND the card is valid
        AND the dispenser contains cash
        AND the customer requests cash} do

  extend CustomerWithdrawsCashSpec
  should_debit_the_account
  should_dispense_cash
  should_return_the_card
end

Thanks,
Brian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/rspec-users/attachments/20061121/64922509/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: customer_withdraws_cash_spec.rb
Type: application/x-ruby
Size: 2383 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/rspec-users/attachments/20061121/64922509/attachment-0002.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: customer_withdraws_cash_alternative_spec.rb
Type: application/x-ruby
Size: 2300 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/rspec-users/attachments/20061121/64922509/attachment-0003.bin 


More information about the rspec-users mailing list