Csteele5
Csteele5

Reputation: 1292

Yielding self to rspec test inside each loop yields last known state

I'm writing some rspec tests for some web-pages. One of the pages contains several links that I want to test as a group. So my test looks something like this

require 'spec_helper'

t = Page.new
t.test do |t|
  describe 'a thing' do
    it 'should not be last' do
      t.title
    end
  end
end

So when I call t.title I am actually calling that on the the following Page object being yielded (by itself) down below.

and my Page object looks like this

class Page

  attr_accessor :driver

  def initialize()
    @driver = Watir::Browser.new :phantomjs
    @home = ''
    @driver.goto(@home)

  end

  def visit(url)
     @driver.goto(url)
  end

  def title
    @driver.title
  end

  def test
    @subpages.each do |page|
      visit(page)
      yield self  
    end
  end

end

So now when I run rspec, what ends up happening is the test will run as many times as I expect it to, however it runs each time it yields the object in the state it's in during the final iteration of visit. So it's not really testing the pages the way I want it to, it's testing the last page in the list.

Am I incorrectly using yield or self here? It seems pretty straightforward: pass the test as a block to the Page object's test method and have it run the test on itself.

Any tips? I'd like to be able to keep all the tests clean, and all the logic in the page object, but this is hindering me from doing so.

Upvotes: 0

Views: 362

Answers (1)

Peter Alfvin
Peter Alfvin

Reputation: 29439

Within the scope of a given file, RSpec examples/tests don't get executed until they all have been defined. You're iterating through the page defining all these examples, but RSpec is collecting and not executing them until the iteration is complete, at which time the value of t remains unchanged and corresponds to the final state of the page.

Upvotes: 1

Related Questions