Tibor Nagy
Tibor Nagy

Reputation: 1236

How can I run the same tests in rspec/capybara with one parameter throgh iteration in an array

I am working with rails rspec/capybara/declarative_authorization. I have to run the same test with a lot of different users:

 describe "Revision in root folder" do
   before do
     with_user(@guest) do
       visit revisions_path
     end
   end
   it { should have_selector('div.alert.alert-error', text: auth_error_text) }
 end
...
 describe "Revision in root folder" do
   before do
     with_user(@user1) do
       visit revisions_path
     end
   end
   it { should have_selector('div.alert.alert-error', text: auth_error_text) }
 end

The only parameter is the user calling with_user. Can I somehow use only one describe block, and iterate through an array of users, to keep my test DRY. It is important, that @guest and @user1 are created in a before(:all) block, so they are not available at the parsing of the spec.

Any help is appreciated.

Upvotes: 1

Views: 2102

Answers (4)

Semjon
Semjon

Reputation: 1023

Modern version of Rspec allows to duplicate examples without monkey-patching. Please have a look to this gist https://gist.github.com/SamMolokanov/713efc170d4ac36c5d5a16024ce633ea

different users might be provided as a shared_context - user will be available in actual tests:

  shared_context "Tested user" do
    let(:user) { |example| example.metadata[:user] }
  end

During clone, we can do

  USERS.each { |user| example.duplicate_with(user: user) }

Upvotes: 0

Mihail  Matrosov
Mihail Matrosov

Reputation: 1

I had the same problem and I resolve it in following way:

[:user_type_1, :user_type_2].each do |user_type|
   let(:user) { create(user_type) }
   before do
     with_user(user) do
       visit revisions_path
     end
   end
   it { should have_selector('div.alert.alert-error', text: auth_error_text) }
end

Upvotes: 0

Paul Fioravanti
Paul Fioravanti

Reputation: 16793

Not that much DRYer, but do you mind nesting your specs? This way you'll be able to account for any different expected behaviour between users and guests.

describe "Revision in root folder" do
  context "as a guest" do
    before do
      with_user(@guest) do
        visit revisions_path
      end
    end
    it { should have_selector('div.alert.alert-error', text: auth_error_text) }
  end

  context "as a user" do
    before do
      with_user(@user1) do
        visit revisions_path
      end
    end
    it { should have_selector('div.alert.alert-error', text: auth_error_text) }
  end
end

If you end up with many more duplicate it statements, you could probably refactor them up into a shared example.

Upvotes: 0

ted
ted

Reputation: 5329

describe "Revision in root folder" do
  users = [@guest, @user1]
  users.each do |user|
    before do
      with_user(user) do
        visit revisions_path
      end
    end
    it { should have_selector('div.alert.alert-error', text: auth_error_text) }
  end
end

Upvotes: 2

Related Questions