8

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!

Peter Brown
  • 50,956
  • 18
  • 113
  • 146
pitosalas
  • 10,286
  • 12
  • 72
  • 120

2 Answers2

13

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.

froderik
  • 4,642
  • 3
  • 33
  • 43
Peter Brown
  • 50,956
  • 18
  • 113
  • 146
  • Here are some more perspectives on it: http://stackoverflow.com/questions/3604564/rspec-vs-shoulda – Peter Brown Jan 06 '11 at 01:37
  • I'd love some examples of things you do with the combo that couldn't be done with one or the other. If there are ways I can clean up my tests, I am all for it. I was using shoulda + matchy together, then found that rspec basically did that and went from there. Is it just things like the controller matchers? – Chris Heald Jan 06 '11 at 01:39
  • I updated my answer with some of the shoulda tests I have. One rule I tend to follow is that Shoulda is used for Rails' built in Class macros like validations and relationships, and Rspec is for more complex tests where mock objects and method stubbing is required. – Peter Brown Jan 06 '11 at 01:58
  • +1 They're complimentary, at least when used with Rails. Lets you do things like `it { should validate_presence_of(...) }`. – Robert Speicher Jan 06 '11 at 21:07
  • +1 @Beerlington, can I ask whether in your model test files you also tend to have some kind of `context 'database schema'` where you would use shoulda methods like `have_db_column` and `have_db_index`? Or is this considered too excessive, unnecessary and/or low-level to put in a model test file? – Paul Fioravanti Aug 19 '12 at 07:40
  • 2
    @PaulFioravanti I don't test for those. I only test things that are related to behavior and I don't consider the presence of a column or an index behavior. Database columns don't just disappear unless someone intentionally removes them, but you can protect against that with code reviews and trust :) – Peter Brown Aug 19 '12 at 13:45
0

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.

Chris Heald
  • 61,439
  • 10
  • 123
  • 137