What Not to Test
I've now seen multiple claims amounting to something like, "I built this Rails application with just testing." I think it's great that people can do that. They are obviously smarter than me. I need a browser to build a Web application.
I do test my Rails projects, of course. I'm a huge fan of testing and I'm always telling people how much it could help with their work. However, I believe there's a time to test and a time not to, if you can imagine that. Yes, you heard me right, there are things I don't test and I'm sure this next revelation will shock you even more:
I don't test Rails views.
Now before everyone fires up their mail client and pours on the hate mail, let's make sure we are very clear about what I just said. I do write thorough unit tests for all of my model classes, of course. I also test the controllers as much as possible. I make sure the data I expect ends up in the right instance variables with the magic
assigns(). I also use the
Hash to validate what I am remembering about the user. If a controller action is a complex logic branch that can end up in several different places, I will also make sure I add some assertions to verify that the right template handled the response.
All I said is that I don't test the view layer. I'm talking about the final HTML pages here. Those are what I don't validate.
Now that we are clear about what I don't test, let's cover why I don't. I assure you this isn't some random choice or even an attempt to avoid work. I have found that not testing the views works out better for me and I want to share my reasons with you.
- As I've already hinted at, I'm constantly viewing my Rails work in a Web browser. If there's a problem, I'm going to see it pretty quickly. In fact, I have a much better chance of seeing some browser oddities than I do of successfully coding a test to catch them, I think.
- If you are doing Rails correctly, the only programming logic in your templates is flow control, right? (Helpers are a legitimate exception here, but you can test them normally.) That makes your templates little more than data files in my eyes and I don't validate the contents of data files.
- HTML pages change rapidly. Practically each time I look at a page, I will tweak something. If that breaks a test, I just have to change two things instead of one. To me, that's the whole point of data files, I can change them without worrying about the code that relies on them.
- The main tool for testing views,
assert_tag(), is a clever but flawed helper. Have you seen what it spits out when the test starts failing? "I couldn't find tag xyz in this-giant-mess-of-unformatted-HTML." To me, that's like saying, "I couldn't find this needle in this haystack. You try." Even a great tool like
unit_diffcan't fix that.
All of that adds up to the fact that I am already visually checking what view tests would be checking. I feel I am more thorough and accurate than the tests I know how to write for this process. It's also a low risk area, since I'm not hiding any important functionality in the templates. Given all of the above, I feel I lose nothing and gain speed by not writing those tests.
This is just my system, of course. Obviously, others are doing things differently. I just wanted to share what is working for me.
Gregory Brown January 17th, 2006 Reply Link
I think the biggest issue here is that in most cases, unit testing will save you time and increase the reliability of your code.
In the case of views, if they're done right they won't have much important logic in them, as you mentioned. So the likelyhood is very high that it'll take me less time to refresh my browser and visually inspect the changes than it would to code a complete test ensuring my underlying output is EXACTLY what I wanted.
Of course, there are people who are incredibly fast at writing HTML and can visualize it through code. It doesn't hurt to have tests if they're increasing productivity and reliablity.
However, for the rest of us, a little pragmatism about testing doesn't hurt ;)
Nice article, James.
Pat Maddox January 30th, 2006 Reply Link
I've never tested a view in my life. I just don't care enough, to be honest. HTML code is something that for structure can be validated, and for logic be observed.
I want to know when my code actually breaks. The logic is what's important to me, and I in general could care less about the presentation. If some bit of info isn't showing up in a view, I'll find out in about two seconds when I or someone else checks it out. As long as the info is accessible, I'm happy. Maybe this comes from being 100% hacker and 0% designer.
Also, I've often laughed when I see people talking about testing the view. I always think it's completely absurd, and I'd rather be coding real tests and real logic.
With one Rails application under my belt now, I have to agree. Of course, the trick is to resist the temptation of sticking code in the view that belongs in the controller. :)
James Edward Gray II February 6th, 2006 Reply Link
That's a very good point. Code in Rails views should be for flow control only. Anything else belongs in controllers or helpers. You do have to keep an eye on that and force yourself to refactor it back out when you find it.
James O'Kelly December 5th, 2007 Reply Link
I agree completely. We spend so much time doing regression testing through the front facing part of our application at every step, putting tests for views just adds extra un-needed complexity.
I LOVE your TextMate book! Are you planning on doing some TM related posts?
James Edward Gray II December 5th, 2007 Reply Link
I do need to do some TextMate related posts. I'll think on that and see what I come up with.
I'm glad you liked the book. Thanks for the support!