[rspec-users] [rspec] loading specs as an object model without running them
Marty Andrews
marty at martyandrews.net
Wed Apr 29 07:50:27 EDT 2009
On 29/04/2009, at 9:41 PM, David Chelimsky wrote:
> On Wed, Apr 29, 2009 at 6:09 AM, Marty Andrews
> <marty at martyandrews.net> wrote:
>>
>> On 29/04/2009, at 8:54 PM, David Chelimsky wrote:
>>
>>> On Wed, Apr 29, 2009 at 1:23 AM, Marty Andrews <marty at martyandrews.net
>>> >
>>> wrote:
>>>>
>>>> I'd like to load all of my examples into memory without actually
>>>> running them, so I can traverse the object tree and get
>>>> descriptions
>>>> etc. I'm finding it tricky to figure out how to do that though.
>>>> There seems to be an inherent assumption in the framework that that
>>>> examples will actually run.
>>>>
>>>> So basically, I want to do something like this:
>>>>
>>>> examples = load_examples_without_running
>>>> examples.each {|example| puts example.description}
>>
>> [snip]
>>
>>> As for getting a handle on the objects, this is something that is
>>> not
>>> really baked into RSpec, but will definitely be baked into
>>> rspec-2.0.
>>> Work on this will start later this year (probably not until after
>>> the
>>> rspec book is off to print). Goals for it include a very clean
>>> separation of the DSL and the underlying object model and a very
>>> lightweight runner.
>>>
>>> So in the short run, your best option is to use --dry-run and
>>> understand that you only get value out of it if you write docstrings
>>> for all of your examples.
>>
>> Ok. It's actually a bit more complicate than that. Let me give
>> you an
>> insight into where I'm headed.
>>
>> I'm working into a big corporate in Australia, and they are demanding
>> traceability of tests back to requirements. I'm already using
>> Mingle to
>> manage story cards, and I'm hoping to let the testers build in the
>> traceability via code. So I've got a Mixin to the examples so that
>> I can
>> declare the id of the story that the test maps to. It looks
>> something like
>> this:
>>
>> describe FunctionalArea do
>> it "automates some acceptance test declared on a story" do
>> traces_to_story 35
>> # test implementation
>> end
>> end
>>
>> So now, I want to be able to walk the object tree, getting the
>> descriptions
>> *and* the story id's. Mingle has a nice RESTful API that I've
>> already used
>> to slurp up detail about stories. Now I just want to wire in this
>> last bit
>> of information to tick the traceability box without any human
>> needing to do
>> the work.
>>
>> I'll have a look at the --dry-run option and see where it gets me.
>> If
>> you've got any more tips, let me know. I'll send in a code snippet
>> if I
>> manage to get it going :)
>
> There *is* something you can *almost* use for this, but it's
> incomplete at the moment. RSpec let's you write your own output
> formatters, which receive messages for every example group and example
> as they are run. Currently, the object passed to example_started (and
> a few other methods) is an ExampleGroupProxy, which includes an
> options hash passed to the example. So if you do this:
>
> it "automates some acceptance test declared on a story",
> :traces_to_story => 25 do
> # ...
> end
>
> Then you could do stuff like:
>
> def example_started(example_proxy)
> traces_to_story(example_proxy.options[:traces_to_story]
> end
>
> This should solve your problem assuming that you have docstrings for
> all of your examples. The big missing piece at this moment is that the
> ExampleGroupProxy (passed to example_group_started) doesn't include
> the options hash, but I'll happily add that tonight.
Yep - no problems there. I reckon about 98% have docstrings. I can
easily add the remainders.
> To see this in action, try this:
>
> * in options_formatter.rb
>
> require 'spec/runner/formatter/base_text_formatter'
>
> class OptionsFormatter < Spec::Runner::Formatter::BaseTextFormatter
> def example_started(proxy)
> puts proxy.options.inspect unless proxy.options.empty?
> end
> end
>
> * in example_spec.rb
>
> require 'spec'
>
> describe "example" do
> it "supports options", :like => 'these' do
> # no need for anything here
> end
> end
>
> Now, on the command line:
>
> $ spec --require options_formatter.rb example_spec.rb --format
> OptionsFormatter
> {:like => 'these'}
>
> Formatter API is here:
> http://rspec.rubyforge.org/rspec/1.2.4/classes/Spec/Runner/Formatter/BaseFormatter.html
>
> Let me know if this is a good direction for you and I'll add the
> options hash to the example group proxy.
I reckon this would be great *if* it will still work with the --dry-
run option. Most of the examples are actually integration tests that
call out to other tools as they run, so the build is S..L..O..W (over
an hour). I want to be able to generate the report without actually
running the tests.
-- Marty
More information about the rspec-users
mailing list