I was planning some additional posts before this one, but this really got on my nerves.
Rails really wants to make it easy for you to test your programs. It provides a whole framework for testing. That's great and commendable.
So, I finally took the plunge and started my project. I built some models, controllers and views using Rails 2.0's spiffy new RESTful scaffold generator, added user login management using the restful_authentication plugin (more on this in a later post), and tried running all the generated tests.
Errors, failures and what not, and I haven't written any of these tests, they were all generated by the generators!
The first problem was that all the functional tests should login before the test is run. OK, that makes sense, the generator couldn't know I was behind the authentication "wall". Fine, but the restful_authentication plugin's documentation is practically non-existent.
After searching around I found several forum posts that point to the login_as helper method. Just stick it in your setup method, they say, and you're home free:
def setup
login_as :quentin
end
the rest of the test
should work as before (
:quentin and
:aaron are the automatically generated users, they apparently work for
example.com).
However, no such thing happened.
After, endless trials and errors, detours and hacks, I tried adding
login_as to each method and
not through
setup. Suddenly some of the tests passed without a problem. Those that didn't failed due to some other strange reason.
Now, remember, these are
all auto-generated tests!
Anyway, it seemed there was some problems accessing a model with
:id of 1. I checked the
automatically generated fixtures, and, indeed,
:id was not set! Didn't anyone test this Rails release?! This is the newest public release of Rails.
So, I added the
:ids and lo and behold,
most of the tests now passed.
I later
discovered that one of the fixes done in Rails 2.0.2
were:
- Fixed that functional tests generated for scaffolds should use fixture calls instead of hard-coded IDs
scroll down, it's the forth item from the end. Of course, this doesn't help me, since I scaffolded using ver. 2.0.1. Arghhhh!
By adding the mandatory record fields in the
test_should_create_* tests, I got all the test to run properly. Being a rookie this also took me a while to figure out thanks to the "helpful" error messages.
What still bugged me was why I couldn't use the
setup method. After some serious and associative digging I found
this little post:
Rails 2.0 introduces a new (better) way to create your functional test cases. Instead of subclassing Test::Unit::TestCase directly, you can now subclass ActionController::TestCase, which will take care of the setting up the request/response environment for you.
...
And therein lies the gotcha: if you go ahead and create your own setup method not realizing that you’ve inherited one, you’ll clobber the one defined in the superclass. So, when you’re defining your own setup method, remember to call the original one using super...
so when I changed my
setup method to look like this:
def setup
super
login_as :quentin
end
everything suddenly worked.
Now, it took
Jeffrey Allan Hardy 15 minutes to figure this out and he wrote a
book about Rails and is a partner at a boutique Rails consulting shop (whatever that means). It took me hours!
He updated his post to mention that this "gotcha" has been fixed on the Rails Trac (the Rails source repository) but that isn't much consolation nor use to me.
All my tests now pass and I'm going to sleep.
If you found this post helpful, please leave a message in the comments.
If you want to hear more about my mis-adventures with Rails, subscribe to the blog feed and you just might not have to go through it yourself.