Getting "by" with rspec feature specs

June 10, 2013 Stephan Hagemann

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).

About the Author

Biography

Previous
When pairing doesn't transfer knowledge fast enough
When pairing doesn't transfer knowledge fast enough

Pairing is great for knowledge transfer. With a reasonably sized 3 pair project, you can completely avoid ...

Next
22 Billion Served: Julien Genestoux of Superfeedr
22 Billion Served: Julien Genestoux of Superfeedr

Superfeedr delivered a total of 22,408,346,028 entries at the time of this interview. Read about how founde...