Reputation: 161
I'm new to the world of rails and test driven development. For TDD, I'm using RSpec and Capybara. Currently, I'm working on a tutorial to learn more about Rails and the author is using following syntaxes:
page.should have_title('All users')
expect(page).to have_selector('li', text: user.name)
Since it seems that both are interchangeable I'm wondering when to use which syntax? Because, for the described case above, I could also write:
page.should have_title('All users')
page.should have_selector('li', text: user.name)
Which basically does the same, right?
Also, when should I use "specify" instead of "it"?
it { should have_link('Sign out', href: signout_path) }
specify { expect(user.reload.name).to eq new_name }
In this case, I could also write:
it { should have_link('Sign out', href: signout_path) }
it { expect(user.reload.name).to eq new_name }
I guess the decision of which one to use is based on what I want to express. Maybe, you can help me out here?!
Thanks!
Upvotes: 7
Views: 2998
Reputation: 364
When you have the same subjects for multiple lines, you could DRY it up using subject
and should
. Using expect
can actually make your code less DRY.
See: http://betterspecs.org/#subject
You gave this example:
page.should have_title('All users')
page.should have_selector('li', text: user.name)
It's better to say:
subject { page }
it {
should have_title('All users')
should have_selector('li', text: user.name)
}
This is interesting because in the betterspecs link above, the preferred way is not to use expect
, but to use should
in favor of DRY. You can see myronmarston's comment about this here: http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#comment-564045016
Upvotes: 0
Reputation: 31756
page.should have_title('All users')
expect(page).to have_selector('li', text: user.name)
Go with the latter one, it's newer, they're pushing in that direction. I don't know if they have the intent of deprecating the former, but if they do, you won't have to go update all your code.
it { should have_link('Sign out', href: signout_path) }
specify { expect(user.reload.name).to eq new_name }
They are aliases, so just choose the one that makes it clearer. If you name your tests, you will know when to use which (example).
it { should have_link('Sign out', href: signout_path) }
Frankly, I avoid the non-named spec style. It's a bit too magical, making it difficult to reason about, and often requiring acrobatic setup to get the subject to work out correctly. Also, I run my specs with --format documentation
, and the auto-generated message is never what I want. In this case, I'd want to say something like it 'has a signout link'
Upvotes: 9
Reputation: 339
the expect syntax is the new syntax, its also the one that is recommended by the rspec team, see: http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
Regarding it and specify, see: Difference between an it block and a specify block in RSpec
Upvotes: 2