milchschaum
milchschaum

Reputation: 161

TDD with Capybara (Rails); difference between page.should and expect(page).to?

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

Answers (3)

creativehandle
creativehandle

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

Joshua Cheek
Joshua Cheek

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

jvanbaarsen
jvanbaarsen

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

Related Questions