rSpec vs Shoulda confusion - ruby-on-rails

I started reading a book about rSpec as my basic intro to testing my Rails app. I started writing tests like:
it 'is valid with a name' do
coaster = FactoryGirl.build(:coaster)
expect(coaster).to be_valid
end
But then someone pointed me at Shoulda and can now write tests like:
it { should validate_presence_of(:name) }
Note: I realise the two tests posted are not the same, merely just examples of each type.
What I need some clarification of is, is Shoulda an alternative to rSpec or is Shoulda an addon to it?
Which way would others go about this? The Shoulda tests seem simpler and shorter overall.
Basically any thoughts and comments would be helpful.

Shoulda just adds additional matchers to RSpec.
http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames

The BDD style is exposed through expect, expect is more natural language assertions. First of all, notice that the expect require is just a reference to the expect value, whereas with the should require, the value is being executed. The should style extends each object with a should property which is called monkey patch in ruby. Here is a good article which explains and compares this two assertion mechanism.

Related

Reform: Dry-Validation Matchers

I'm looking for a convenient way to test validations of a Reform-based form object.
Are there any matchers (like shoulda matchers for testing ActiveModel::Validations) to test dry-validations? Is this even the way to go?
There is this: https://github.com/bloom-solutions/dry-validation-matchers
I've enjoyed using shoulda matchers in the past. It helps to greatly cut down on the repetitive code where you first create a valid object and then change the attribute affected by the validation to an invalid value to carry out the test.
In the end this is just a matter of taste.

Is there an alternative to "it" in RSpec tests?

Some RSpec methods have aliases for how you phrase them e.g. describe and context both do the same thing.
It's not always useful to start a spec statement with it - are there any alternatives to how one can phrase that part of the test?
e.g. it might be nice to phrase the following:
context "when copying a Page object" do
expect_that "the image gets copies" do
...
end
end
Are there aliases for it that one can use?
specify is a minimally documented synonym for it. example is also a synonym, but I'm not aware of any documentation.
There's also its, which has been factored out to a separate gem as of RSpec 3.0.

What does expect() do in rspec/cucumber?

In Michael Hartl's Rails Tutorial, many examples use an expect() method. Here's one such example in a cucumber step definition:
Then /^she should see her profile page$/ do
expect(page).to have_title(#user.name)
end
This same example can be written as such to the same effect:
Then /^she should see her profile page$/ do
page.should have_title(#user.name)
end
Why use expect()? What value does it add?
There's a documentation on the rspec-expectations gem about this.
Why switch over from should to expect Basically:
should and should_not work by being added to every object. However, RSpec does not own every object and cannot ensure they work consistently on every object. In particular, they can lead to surprising failures when used with BasicObject-subclassed proxy objects.
expect avoids these problems altogether by not needing to be available on all objects.
A more detailed reasons for this is placed in: RSpec's New Expectation Syntax
expect is a bit more universal. You're passing an object or a block to rspec's expect method, rather than attempting to call a should method on objects that are outside of your control. As a result, expect is coming more and more into favor among developers.

rspec and shoulda - complementary or alternatives?

I've used shoulda for a while, and I've read and played with rspec. I have not done an in depth compare and contrast. But it seems to me like there is some overlap between the two, but that they are not 1-1 replacements.
I am considering writing some unit tests in my rails system with rspec, without replacing all the existing tests that are written with shoulda. Just as a way to get the feel.
Is this a good idea? Can I gradually move from one to the other or am I asking for trouble?
Any clear cut advantages of one over the other that I should consider?
Thanks!
I have to argue against Chris's answer that they are alternatives. I use Shoulda and Rspec together in my Rails application, and they complement each other well.
This combo allows me to write concise one-line unit tests for recurring things like associations and validations, as well as the having the full rspec suite for more complex specs. You get the best of both worlds without any conflicts.
Check out the Shoulda README which shows how to install along side Rspec. It even says it provides "Test::Unit- and RSpec-compatible one-liners that test common Rails functionality. These tests would otherwise be much longer, more complex, and error-prone."
Edit (examples):
At the top of my specs, I always declare my Class relationship and validation tests which are concise and easy to read.
describe Component do
context 'relationships' do
it { should belong_to(:technology)}
it { should have_many(:system_components) }
it { should have_and_belong_to_many(:variables) }
it { should have_many(:images).dependent(:destroy) }
it { should have_many(:documents).dependent(:destroy) }
end
context 'validations' do
it { should validate_presence_of(:make) }
it { should validate_presence_of(:model) }
it { should ensure_length_of(:name).is_at_most(100) }
it { should validate_presence_of(:technology_id) }
end
end
Then the rest of my spec will have more complex tests where I am using mocks and stubs which come from Rspec.
rspec and shoulda are alternatives to each other. I started with shoulda, as well, and moving to rspec is as simple as s/context/describe/, s/should/it/, and you're off to the races. rspec has a bunch of tricks, various integrations, and more complex matchers, so I'm using it more these days myself.
One of my initial frustrations was that it was nearly impossible to find a tutorial that didn't assume Rails and Cucumber. Don't overthink it - there's a lot you can do with it, but you don't have to have a monster of a solution in place before you can use it.

Should I write rails tests with the def or test keyword?

This seems like a simple question but I can't find the answer anywhere. I've noticed that in general, tests in a Ruby on Rails app can be written as:
test "the truth" do
assert true
end
or
def the_truth
assert true
end
It seems newer material writes tests the first way, but I can't seem to find a reason for this. Is one favored over the other? Is one more correct? Thanks.
There has been a shift in recent years from short, abbreviated test names to longer, sentence-like test names. This is partly due to the popularity of RSpec and the concept that tests are specs and should be descriptive.
If you prefer descriptive test names, I highly recommend going with the test method. I find it to be more readable.
test "should not be able to login with invalid password" do
#...
end
def_should_not_be_able_to_login_with_invalid_password
#...
end
Also, because the description is a string it can contain any characters. With def you are limited in which characters you can use.
I believe the first method was implemented starting with Rails 2.2.
As far as I am aware, it simply improves readability of your code (as def can be any function while test is used only in test cases).
Good luck!
As Mike Trpcic suggests you should check out RSpec and Cucumber. I'd like to add that you should also take a look at:
Shoulda (http://github.com/thoughtbot/shoulda/tree/master)
Factory Girl (http://github.com/thoughtbot/factory_girl/tree/master)
Shoulda is a macro framework for writing concise unit tests for your models/controllers, while the second is a replacement for fixtures.
I would suggest doing your testing with either RSpec or Cucumber. I use both to test all my applications. RSpec is used to test the models and controllers, and Cucumber tests the Views (via the included Webrat functionality).

Resources