Topic: rspec'n in a evolving enviroment is tough

Hello RailsForum,

I am learning rspec, but am very frustrated at all the information out there. When I look at all the different rspec examples I find, I don't know what to make of the results. The syntax in each example is different, random bits of code are used to test associations or validators, and it seems like everyone has a different method to do everything.  Sure behavior testing, rspec, and how to do it in rails is always changing, but this is getting ridiculous.

So, If there are any behavior testers reading this, do you mind answering a few questions for a very confused beginner?

1) I have read several articles about testing associations and most of the articles use pieces of custom code to do this. I would think that testing associations would be a fairly common thing in a rails application. Is there an association testing technique built into rspec?

2) So in testing, you are not supposed to hit the database. Let's say you are testing validates_uniquess_of. How are you supposed to do this and not hit the database and still test that it is unique?

3) I also read that you don't need to test code you didn't write (i.e. the associations or validators). Anyone care to comment? Is this why there are no standard means to test associations or validations in rspec

4) Best Practices, the rspec scaffolding helps but am I missing out on other best practices for non standard tasks?


Thanks guys,

Roy

Re: rspec'n in a evolving enviroment is tough

roy wrote:

1) I have read several articles about testing associations and most of the articles use pieces of custom code to do this. I would think that testing associations would be a fairly common thing in a rails application. Is there an association testing technique built into rspec?

I don't know of any, but I'm not sure exactly what you would be testing here? An association will likely be tested at a higher level already so a low level test is usually not necessary.

roy wrote:

2) So in testing, you are not supposed to hit the database. Let's say you are testing validates_uniquess_of. How are you supposed to do this and not hit the database and still test that it is unique?

Instead of saving the record, you can call the "valid?" method on it which will run the validations without hitting the database.

item = Item.new
item.valid?
item.should have(1).error_on(:name)

roy wrote:

3) I also read that you don't need to test code you didn't write (i.e. the associations or validators). Anyone care to comment? Is this why there are no standard means to test associations or validations in rspec

There's the code I posted above for testing validations, not sure what you need to test for associations though.

roy wrote:

4) Best Practices, the rspec scaffolding helps but am I missing out on other best practices for non standard tasks?

I find the code generated by the rSpec scaffolding to be very wrong. Just look at the code to test ratio, the amount of test code is ridiculous. It is also rigid and inflexible which can lead to a lot of work just trying to maintain your tests.

Instead, I prefer to take the much simpler approach. Try to keep your tests as simple as the code you're actually writing for. Don't worry about hitting the database once and a while (unless you have a really large project and need the tests to be super fast). You can see this Railscasts episode on how I test controllers.

All this said, I'm no testing expert. I try not to go overboard with testing because then I spend too much time on it and I don't want to do it. The main thing I'm concerned about is coverage - make sure all the code gets executed. If you can get here then your tests will still be very simple yet you will get a lot of bang for your buck. Testing the functionality is important too, but is a lower priority for me. Here's basically what I do for each layer.

View Layer: Very few tests here. I just make sure the coverage is good so it catches any syntax errors. This keeps it really flexible.

Controller Layer: Again, coverage is the main concern. On top of this I also pass a few parameters and check the response behavior.

Model Layer: Here's where I go all out and test the actual functionality. Again, make sure you have code coverage (call every model method) but also check the functionality of each method to make sure it behaves properly. This is where the business logic is and where it's most important that things behave the way you expect them.

Railscasts - Free Ruby on Rails Screencasts

Re: rspec'n in a evolving enviroment is tough

Ryan,

This is great advise for a beginner like me. I'm sure more rspec posts will be coming from me in the future... but this was very helpful.

Roy