7

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!

milchschaum
  • 161
  • 1
  • 7

3 Answers3

9
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'

Joshua Cheek
  • 30,436
  • 16
  • 74
  • 83
  • Thanks for your answer! I guess I just have get used to the whole tdd thing and also to the syntax in order to get a feeling when which alias to use. btw: the "--format documentation" is pretty nice. – milchschaum Jul 19 '13 at 11:47
2

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

Community
  • 1
  • 1
jvanbaarsen
  • 339
  • 2
  • 12
  • The blog link is invaluable. It also helps in explaining how we can disable the use of should altogether on new projects. Good one! – Gurpreet Jan 05 '14 at 14:10
0

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

creativehandle
  • 364
  • 5
  • 10