Rspec-core: There should be a way to run single specs in a shared group in isolation

Created on 20 Jul 2010  ·  10Comments  ·  Source: rspec/rspec-core

Here is an example backtrace gotten from running an entire spec suite that uses shared spec groups

8)
RuntimeError in 'Arel Join#each iterates over the rows in any order'

/Users/apatterson/git/arel/spec/../lib/arel/algebra/relations/operations/join.rb:14:in `hash'
/Users/apatterson/git/arel/spec/../lib/arel/session.rb:38:in `[]'
/Users/apatterson/git/arel/spec/../lib/arel/session.rb:38:in `read'
/Users/apatterson/git/arel/spec/../lib/arel/algebra/relations/relation.rb:21:in `each'
/Users/apatterson/git/arel/spec/support/matchers/have_rows.rb:5:in `have_rows'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/matchers/simple_matcher.rb:16:in `call'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/matchers/simple_matcher.rb:16:in `matches?'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/expectations/handler.rb:11:in `handle_matcher'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/expectations/extensions/kernel.rb:27:in `should'
/Users/apatterson/git/arel/spec/shared/relation_spec.rb:23:
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_methods.rb:40:in `instance_eval'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_methods.rb:40:in `execute'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:53:in `timeout'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_methods.rb:37:in `execute'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:214:in `run_examples'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:212:in `each'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:212:in `run_examples'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:103:in `run'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:23:in `run'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:22:in `each'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:22:in `run'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/options.rb:152:in `run_examples'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/command_line.rb:9:in `run'
/Library/Ruby/Gems/1.8/gems/rspec-1.3.0/bin/spec:5

There are a few problems here.

1) given the backtrace, I have no idea what the context of the shared spec is. Aka, where was it included, what file was it included in, etc... There is the description 'Arel Join#each iterates over the rows in any order', but in a project with a lot of specs, that's basically useless to me.

2) I would like a way to run that single spec in isolation in the context that caused it to fail. I'm not sure of how to do that right now.

Most helpful comment

You can run a single example in a shared group via rspec spec/my_spec_that_contains_the_shared_group.rb --example "hello world"

All 10 comments

David, I think I might have a solution for this:

When "it_should_behave_like" (or the alias) is called, it sets the following metadata on the ExampleGroup:

Name of the shared example group.
File path and line number of "it_should_behave_like" method call.

When an example fails, RSpec will check to see if that example exists in the shared example group. If it does, it will append to the output the file path and line number (stored in the ExampleGroup metadata).

What do you think?

Oh nice I see that metadata is already there :-)

I merged @justinko's patch (3906559d059bcdbd4d15303303c517088b038eeb), which displays the line that calls the shared group, so we now know the context in which it was run. That still leaves open the issue of running a single shared example - but this should help at least to understand when a shared example fails.

You can run a single example in a shared group via rspec spec/my_spec_that_contains_the_shared_group.rb --example "hello world"

Yep - that's true. That's good enough for me. I'm going to close this. @carllerche if you think this is not sufficient, comment here and I'll reopen this.

Crap, found a bug with this:

share_as :MySpecs do
  let(:foo) { described_class # returns nil }

Investigating.

I want to deprecate share_as. It generates a module, which you then use include to include, which has very different implications from creating a nested group, as we do now with shared_examples_for. WDYT?

I completely agree with deprecating it. When I first started learning RSpec, I was confused why there was shared_examples_for and share_as.

I tend to use share_as for the top level group:

describe Model do
  include MySharedSpecs

  context 'it works' do
    it_should_behave_like 'a working model'

I switched to shared_examples_for and all is well. Thanks.

For anyone skipping to the bottom I want to point out that justinko provided a completely satisfactory answer to this above.

You can run a single example in a shared group via rspec spec/my_spec_that_contains_the_shared_group.rb --example "hello world"

Was this page helpful?
0 / 5 - 0 ratings