0
votes

I am using rspec to do some data driven testing. My test reads from a csv file, grabs an entry which is inserted into the text box on the page and is then compared to expected text which is also read from the csv file. All this is working as expected, I am able to read and compare without any issues.

Below is my code:

Method for reading csv file:

   def user_data
      user_data = CSV.read Dir.pwd + '/user_data.csv'
      descriptor = user_data.shift
      descriptor = descriptor.map { |key| key.to_sym }
      user_data.map { |user| Hash[ descriptor.zip(user) ] }
    end

Test:

describe "Text box tests" do

  before :all do
    @homepage = Homepage.new
  end

  it "should display the correct name" do
    visit('http://my test url')
    sleep 2
    user_data.each do |entry|
      @homepage.enter_name(entry[:name])
      @homepage.click_go()
      sleep 2
      begin
        expect(page).to have_css("#firstname", text: entry[:expected_name])
      end
    end
  end
end

The problem is with failures. If I have a failure with one of the tests (i.e the expected text is not displayed on the page) then the test stops and all subsequent entries in the csv are not tested. If I put in a rescue after the expect statement like this:

   rescue Exception => error
     puts error.message

Then the error is logged to the console, however at the end of my test run it says no failures.

So basically I am looking for is, in the event of a failure for my test to keep running(until all entries in the csv have been covered), but for the test run to be marked as failed. Does anyone know how I can achieve this?

2

2 Answers

2
votes

Try something like this:

context "when the user is on some page" do
  before(:context) { visit('http://example.org/') }

  user_data.each do |entry|
    it "should display the correct name: #{entry[:name]}" do
      @homepage.enter_name(entry[:name])
      @homepage.click_go

      expect(page).to have_css("#firstname", text: entry[:expected_name])
    end
  end
end

You will also need to change def user_data to def self.user_data

1
votes

I would advise mapping over the entries and calling the regular capybara method has_css? instead of the rspec helper method. It would look like this:

results = user_data.map do |entry|
  @homepage.enter_name(entry[:name])
  @homepage.click_go()
  sleep 2
  page.has_css?("#firstname", text: entry[:expected_name])
end

expect(results.all?) to be_truthy

if you want to keep track of which ones failed, you cann modify it a bit:

missing_entries = []
user_data.each do |entry|
  @homepage.enter_name(entry[:name])
  @homepage.click_go()
  sleep 2
  has_entry = page.has_css?("#firstname", text: entry[:expected_name])
  unless has_entry
    missing_entries.push entry[:expected_name]
  end
end

expect(missing_entries).to be_empty