Sometimes it's easy to forget, just how important testing has become in the development lifecycle. I recently had to remind myself and others that there are no reasonable excuses not to write tests. I would go as far as saying you're jeopardizing the quality of your software, just because you had no time, were pushed by management, or were just plain lazy.

To some extent I blame Rails for the lack of proper testing in projects using it. It's just too easy to add a new feature here, a line of code there, and hit reload. Works, right? After all, lots of projects have been developed that way.

But for me, there are no excuses. Even though I didn't learn anything about testing at the university, the advantages became crystal clear as soon as I had first contact with JUnit. The ease of writing tests for your applications for me was the killer feature in Rails. It was what attracted me to it in the first place. Writing tests for model, controller, and the whole app? Come on, how painful was (is?) that in the Java world (where I came from, by the way)?

Fret not, I've been falling into the trap of not writing tests for an easy two, three lines of code every now and then. I pretty much agree with Jay Fields, when he says that 100% test coverage is just not something you should try to achieve under any circumstances. But when you find yourself writing action after action, method after method, without writing a single test, it's time to step back and look at the repercussions.

I recently wrote a method that required a slightly more complex setup of objects than usual. It took me a full day to test all the possibilities, and to write the code (about 10 lines). I used factory_girl to build the test setup (pretty awesome by the way), wrote down the required collaborators, and what the method was supposed to do.

One day might seem like a long time, and it usually doesn't take that long, but that piece of code was crucial to ensuring data consistency. Without data consistency, your application becomes fragile, you end up with a database full of dangling references, or your application just ends up in an invalid state and blows up. Worst case scenario of course, but depending on the part of your application, it might just happen.

I didn't want to take that risk, so I took the time, and I felt much better having these tests in place, when I finally finished it. I also got a taste of factory_girl's code and Shoulda, so it was worth it.

Ensuring your code works isn't the only benefit you get. Sooner or later, code needs to be refactored. In my experience, it's a lot harder with untested code. Not only because you don't know, if the code still works after you're done. But because untested code usually ends up being a tangled piece of code glued together bit by bit and over time into something that you just don't want to touch anymore. It just doesn't feel right to change something. And it shouldn't. That's what testing is about. It should make you feel uncomfortable to not have any tests in place for the code you're working on.

With tests in place, refactoring and taking care of legacy code is a piece of cake. You can focus on the task at hand, and stop worrying about if the code will still work. You'll know immediately.

Why should that matter to you? After all, you're building fresh and shiny Rails applications. The plain truth is, every line of code turns into legacy code as soon as you write it, check it in, and put it in production. Someone will have to take care of it at some point, if not you then someone else. If it's you, you're likely going to ask yourself "What the heck was I thinking writing that code?" Look at the tests, and you'll know. If you know a better way to do it, you can just rewrite it, and rest assured that it still works.

It's sometimes hard to explain the business benefit to someone in a management position. Sometimes it makes me wonder why there's still a need to argue about it. But there's still millions of projects working their way onto the surface without a decent test suite.

If you're working on one of them, I advise you to step back for a moment and ask yourself why you're not writing test cases. I bet you can't find any reasonable explanation, because there simply is none. I know, I know, there are always some parts which are harder to test, but there are always ways to get tests into place, and then untangle them. See Michael Feathers' most excellent "Working Effectively with Legacy Code" for more detail on that topic.

It doesn't matter what framework you use. RSpec, Test::Unit, Shoulda, xUnit, anything works that will help you ensure your application is working as it should. As long as you don't use any of them there's a good chance it might just not work at all.

Tags: testing

RailsConf Europe 2008 is over (and has been for a few days now, I know), so it's time for a recap. In all it was much better than I expected, last year's conference was a bit of a disappointment, so my expectations were low enough to be positively surprised.

Bratwurst on Rails was, if not a huge success, a great event nonetheless. Probably because of the rain not as many people showed up. There werre around 200 guests, but I sure hope they had a good time. In the end most of the cupcakes were gone, and all the bratwursts. So it's all good.

Day 1 started with the tutorial sessions, including one I hosted with Jonathan Weiss on deploying and monitoring Rails applications. Over the course of four hours we gave an introduction on deployment setups, doing the dirty-work with Capistrano, and doing basic monitoring. The slides are up on Slideshare, enjoy!

The day ended with a panel consisting of David Heinemeier Hansson, Jeremy Kemper and Michael Koziarski. They talked pretty much with themselves for the lack of questions from the audience. Someone came up with the question (probably for the millionth time), if Rails is gonna switch to RSpec for testing.

RejectConf sure was a highlight in itself. Good fun, entertaining people and drinks in a pleasant environment. What more could you ask for?

Second day started off with David's keynote, and I gotta say, it was most excellent. He talked about legacy code. Still working on the oldest piece of Rails software he knows his fair share about it. Lots of programmers coming to Rails tend to forget that eventually every new project they work on will turn into legacy code, and needs to be maintained. So David's talk took the more inspirational approach, compared to his previous keynotes.

Quick summing up of the day's sessions:

  • Jon Dahl's talk gave a good introduction on MapReduce, not specific to a certain framework, but to how MapReduce works.

  • Yehuda Katz's talk on jQuery sure filled up the seats quickly. And it actually was a pretty good introduction. Favorite quote (more or less accurately): "Valid markup is when every browser can display it, not when the validator says it's valid."

  • Intellectual Scalability presented an approach on how to scale applications by separating them into different micro-applications running on different servers.

  • Wilson Bilkovich's talk on Rubinius gave some updates on the state of Rubinius, but was probably more interesting for people interested in building compilers (LLVM, if you must know).

  • Jonathan's talk on Security on Rails attracted a big crowd too, and rightly so. Hadn't seen it before, so I can safely say I learned some things as well.

The day ended with Jeremy Kemper's keynote, though I think that it'd have fit better into a normal session. It was a good talk on performance of Rails applications, but it wasn't exactly keynote material.

I attended the BoF sessions on MagLev and Merb, and both were pretty good. One thing I didn't understand is the heat some people gave the guy from GemStone. MagLev is still in its early stages, but I'm so looking forward to giving it a spin once it's ready for the public.

On to day two

  • It started off with with Matt Wood's talk on Genomes on Rails. He's working on an impressive project, involving an even more impressive amount of data.

  • Jay Fields talked about lessons learned from functional testing. Pretty good talk. I can't say it was all news to me, but still a good inspiration for people not yet into testing.

  • Justin Gehtland's talk on Small Things, Loosely Joined and Written Fast sure was one of the best of show. He's an excellent presenter, and introduced using ActiveMessaging and RubyCAS (welcome to my list of things to try out) to keep things loosely coupled.

  • For lack of anything more interesting I attended the talk on "Treading Rails with Ruby Shoes". Let's just say it was a different approach on presenting. And that's that.

  • Tammo Freese flashed the crowd with some serious Ruby meta magic afterwards. Tough stuff, but it still matters to people writing and/or using plugins.

  • I finished off the day with Adam Keys' talk on handling complexity in Rails applications. While nothing new to me (I'd used the things he mentioned in several projects already) it gave a pretty good overview on how to handle some of the complexity in Rails applications.

In all it was a pretty good conference, I met a lot of nice people and had a pretty good time. Sadly it won't be in Berlin next year, but let some other European city be the center of the Europe Rails community for a change.

If you're up for more details on the sessions, Clemens Kofler has excellent coverage.

Tags: rails, railsconf, ruby