[rspec-users] [rspec-devel] Specification Reuse to avoid Combinatorial Explosions

David Chelimsky dchelimsky at gmail.com
Tue Nov 21 08:48:17 EST 2006


On 11/21/06, Brian Takita <brian.takita at gmail.com> wrote:
> Hello,
>
> While reading Dan North's BDD tutorial, 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

Interesting ideas. If we pursue this, I'd like to find an approach
that aligns w/ RSpecs current lack of constructs like classes and
modules. So rather than

CustomerWithdrawsCashSpec = context_module do ...

context "..." do
  extend CustomerWithdrawsCashSpec

I'd like something like

context_module :customer_withdraws_cash do

context "...", :customer_withdraws_cash do

That's not exactly right, but you get the idea.

Also - I think it would be really helpful for this discussion if you
*would* post the full specs so we can see what this stuff really looks
like in context.

Thanks Brian.

David


More information about the rspec-users mailing list