Reputation: 4794
Is there a way to group tests conditionally with rspec? By which I mean, is there a way to say "if this variable is some value, run this set of tests. If this variable is some other variable, run this other set of tests"?
Basic Example of where it would be needed (doesn't actually work, obviously, but should show you what I want). Assume the user to be tested is defined elsewhere and the current user being tested is @user. Although you may have better alternatives to that, that's fine.
before do
login_as_user(@user) #This logs them in and brings them to the homepage to be tested
page.visit("/homepage")
end
describe "Check the user homepage"
subject {page}
it {should have_content("Welcome, #{@user.name}!")}
if(@user.role=="admin")
it {should have_link("List Users"}
end
end
Keep in mind I have no control over the user being tested - I cannot create users on the fly, for example, and no given user is guaranteed to exist, and I don't know offhand what combination of roles a given user will have. So I do need some way to say "run this test only if these conditions are met", rather than a way to create situations where every test can be run.
Upvotes: 4
Views: 9832
Reputation: 9203
in the same kind of idea you can use static variables
In order to easily switch between environment, I even use the system global variables
in my spec_helper.rb, I've set the default settings
default_env = {
'SITE_ROOT' => "http://localhost:3000",
'ACCOUNT_ID' => 'user',
'ACCOUNT_PASSWORD' => 'password',
'SUBMIT_REAL_MONEY' => 'false'
}
# setting default env variables if no ENV ones exists
default_env.each do |const_name, value|
val = ENV[const_name].nil? ? value : ENV[const_name]
eval_str = "#{const_name}='#{val}'"
puts eval_str
eval eval_str
end
Then I can specify my settings in the command line calling my specs:
SITE_ROOT='https://my.production.site/' SUBMIT_REAL_MONEY=true rspec
And here is a spec behind a simple condition:
if SUBMIT_REAL_MONEY == 'true'
it { should respond_with 200 }
end
Upvotes: 0
Reputation: 4794
Okay, apparently the issue was as simple as this: @user is an instance variable, which only exists when the tests are being executed. Dynamic generation of tests does not work with instance variables for that reason.
However, by declaring it as a local variable somewhere outside any test-style blocks (before, after, it or specify), you can have access to it for the conditional logic.
The solution was as simple as taking the @ sign off the front of the user.
Upvotes: 2
Reputation: 96914
You can use a let
(or possibly let!
) to define who the user being logged-in should be. (Obviously replace @regular_user
& @admin_user
with the appropriate factory/fixture/etc.)
before do
login_as_user(user)
page.visit "/homepage"
end
let(:user) { @regular_user }
describe "Check the user homepage" do
subject { page }
it { should have_content "Welcome, #{@user.name}!" }
context "when an administrator" do
let(:user) { @admin_user }
it { should have_link "List Users" }
end
end
Upvotes: 2