[rspec-users] how to pass objects from spec to formatter from before :all block?

David Chelimsky dchelimsky at gmail.com
Sun Mar 7 08:12:09 EST 2010


On Sat, Mar 6, 2010 at 12:33 PM, Jarmo Pertman <jarmo.p at gmail.com> wrote:
> Since i'm using Watir
> then i usually open up the browser in
> before :all block like this:
> before :all do
>  @browser = Watir::Browser.new
> end
>
> and then in the formatter I'm saving html of the browser - thus
> needing to access the browser object.

You should have access to it from within each example. This would be a
bit noisier, but you could do this:

before(:all) do
  @browser = Watir::Browser.new
end
before(:each) do
  options[:browser] = @browser
end

Even though that's noisier, you could easily encapsulate that in a method:

def with_new_browser
  before(:all) do
    @browser = Watir::Browser.new
  end
  before(:each) do
    options[:browser] = @browser
  end
  yield
end

describe "the home page" do
  with_new_browser do
    it "looks awesome" do
      # ....
    end
    it "takes you where you want to go" do
      # ...
    end
  end
end

> I could solve it currently by using before :each block as shown in my
> first post or a global variable (not nice at all), but i thought that
> it would be more logical to set it into options in before :all once.
>
> Also, if using before :each solution and something fails in
> before :all, then formatter doesn't know currently anything about the
> browser object and cannot save the html or anything. It's little bit
> bad, since let's say if i do also some "setup actions" in before :all
> before the actual tests and what if something fails there?

after(:each) and after(:all) are guaranteed to run regardless of what
happens in before(:each), before(:all), and the examples
themselves. So you could deliver the browser there:

def with_new_browser
  before(:all) do
    @browser = Watir::Browser.new
  end
  yield
  after(:each) do
    options[:browser] = @browser
  end
end

> But what would happen if example_group options would be merged with
> example options?

In rspec-1 that would be problematic, but this is already supported in
rspec-2 out of the box, so you may want to give rspec-2 a try.

>
> Any other solutions?
>
> Jarmo
>
> On Mar 6, 7:28 pm, David Chelimsky <dchelim... at gmail.com> wrote:
>> On Sat, Mar 6, 2010 at 11:09 AM, Jarmo Pertman <jarm... at gmail.com> wrote:
>> > Hello.
>>
>> > I need to pass something from before :all to formatter. I know that i
>> > could use options hash from spec and then get the value back in
>> > formatter, but it doesn't work when i'm doing it from before :all.
>>
>> > So, this work:
>>
>> > # in spec
>> > before :each do
>> >  options[:something] = 1
>> > end
>>
>> > # in formatter
>> > def example_failed(example, counter, failure)
>> >  puts example.options[:something] # outputs 1
>> >  super
>> > end
>>
>> > But if i try to do the same thing from before :all, then it doesn't
>> > work.
>>
>> > So i looked into the source of RSpec and in example/example_methods.rb
>> > in method set_instance_variables_from_hash there is a line which
>> > ignores some instance variables among with others @_proxy, which has
>> > this option hash initialized in before :all and that's why it's not
>> > getting into the formatter - in other words it is just dropped.
>>
>> > Is this a bug or expected behaviour? If it's expected then what's the
>> > reason and how could i get the desired results of passing something to
>> > formatter from before :all?
>>
>> > Can't we just pass this options hash along?
>>
>> It was never intended that you would set values on options from inside
>> an example and access them in a formatter. You've happened on
>> something that just happens to work because we're using a standard
>> Ruby data structure.
>>
>> The reason it won't work for before(:all) is that before(:all) gets
>> run before any of the examples are run - so it doesn't have access to
>> the options hash, which is created per example in rspec-1.
>>
>> What sort of information are you trying to get to your formatter?
>> Maybe there is a different way to do it.
>> _______________________________________________
>> rspec-users mailing list
>> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list