If you find that you are making your rspec feature specs longer and longer to cram more coverage in or to prevent the setup costs for more, shorter tests, you will probably have found that it becomes very hard to figure out what’s going on. If you find yourself wanting to add comments to your specs to state what is happening, like so:
it "allows the user to manage her account" do
#Login user
visit "/login"
fill_in "Username", :with => "jdoe"
fill_in "Password", :with => "secret"
click_button "Log in"
expect(page).to have_selector(".username", :text => "jdoe")
#Account management
click_link "Account"
expect(page).to have_content("User Profile")
...
end
Why not throw this code into your spec_helper.rb…
def by(message)
if block_given?
yield
else
pending message
end
end
alias and_by by
… and replace the above section with this:
it "allows the user to manage her account" do
by "logging in the user" do
visit "/login"
fill_in "Username", :with => "jdoe"
fill_in "Password", :with => "secret"
click_button "Log in"
expect(page).to have_selector(".username", :text => "jdoe")
end
and_by "managing the account" do
click_link "Account"
expect(page).to have_content("User Profile")
end
...
end
Instead of having comments, which I personally am trained to a) ignore and b) expect to be outdated, I now have a block which denotes that a part of the spec as doing something specific. I like to think that the benefit of the block over the comment is that
- it has a start and an end (and thus adds programmatic structure),
- it adds indentation (and thus visual structure),
- it can have behavior (like the use of rspec’s
pending
).