views:

174

answers:

7

I have a few medium-sized Rails apps that I work on routinely, and only one of them has any unit tests at all. But I have seen the light and I want to change all that, except... I don't have the time to go in and starting writing tests class by class or something like that.

How do you start writing unit tests on an existing -- and working -- codebase with limited time? For example, since any approach would have to be incremental, how would you order your unit-test writing? Start with superficial tests, then move on to more coverage, or cover just a few classes... etc.

Note: I am asking this question thinking about Rails, but really I'm interested in how it applies to any language.

Edit: Note, this question is not the same as this other one. The other one asks how hard this is, and was the result worth it. I'm asking about how to add unit tests.

A: 

Increasing code coverage is an excellent way to get a new recruit familiar with a codebase.

Other than i think you just need to find time, there is no magic solution!

Paul Creasey
+9  A: 

Here is how I usually start adding unit tests to a project that didn't start out that way: Wait for someone to file a bug, then write a unit test that reproduces the bug. Then fix the unit test. This not only starts building unit tests, but now no one can accuse you of a regression for the given bug.

James Kingsbery
Nice, that's kind of what I had in mind.
Yar
Unit tests != regression tests.
Arnis L.
Nevermind. I got the idea.
Arnis L.
+5  A: 

My answer isn't specific to Ruby on Rails. Next time you need to touch the codebase, to fix a bug or add a new feature, write tests for the parts of the code you're touching. If you can spare a couple of minutes, add some related tests. If you find that you need to refactor, go ahead and write the tests to support that. Over time you'll build up the test coverage, and you'll find you always have tests for the areas you need them in (because those are the tests you're writing).

Graham Lee
I like that answer, thanks
Yar
Keywords here - "if you can spare a couple of minutes". As I've noticed, projects without unit tests aren't unit tests friendly at all. Those minutes could grow into hours and days rapidly.
Arnis L.
@Arnis L., as I've mentioned in my comments to another answer, dynamically-typed languages are friendlier than others, so you can always make things fit. That said, I'll check back in a few months and see if I still think that :)
Yar
@Arnis L. the reason your other post was downvoted is that we assumed that you were joking. It's actually an interesting answer, if you want to put it back, please.
Yar
@yar I'm standing brave and facing down votes w/o fears! ;)
Arnis L.
@yar i undeleted just because You said it was interesting. but it's quite useless - you didn't ask if unit testing is necessary and i kind a forgot that we are talking about ruby. dynamic languages almost forces You to write tests so omitting them isn't an option as i thought it might be (that could actually help for some cases).
Arnis L.
@Arnis L., there's an answer in there somewhere (in the newest version). You might just want to move stuff around in your answer using the "edit" button.
Yar
+2  A: 

One of the problems I faced when I started writing real unit tests (with mocks and etc) is that I had to go back and change the code to support the injection of the mock objects mostly through the extraction of interfaces. I believe it will be pretty hard for you to do that on an existing system without some sort of refactoring.

Otávio Décio
Interesting. What language were you working in?
Yar
@yar - C#, but I suspect the same to be true of other languages.
Otávio Décio
Not sure about that: I believe that the more dynamically-typed the language is, the easier it is to add more unit tests. Ironically, the more necessary they are too, because you get no compile-time safety. I'm not really convinced about tests for Java, but for Groovy I'm sure that I cannot live with them (though I have thus far).
Yar
A: 

In the long run, unit testing should make getting (working!) functionality to the users faster.

If it's not accomplishing that, it's not worth the time.

Dean J
trying to avoid the debate on Unit Testing in this question. But while we're here, I think that with a dynamic language like Ruby, you must Unit Test.
Yar
@yar that point makes my answer utterly useless. :)
Arnis L.
@Arnis L., no: I think your answer is worth something. But perhaps not for this question :)
Yar
@yar it's just the same idea that one should know all or at least most options (even those that usually sounds completely wrong) before he continues instead of picking first one that kind a fits.
Arnis L.
A: 

With limited time? Facing deadlines?

Forget about unit tests!

Cowboy coding 4 the win!

Hack features together until it's not too late and client haven't sued Your company.

P.s. For your own safety - do not forget to inform about situation your PM.


Strange that down votes avalanche haven't started yet. Maybe it's not so bad and telling NOT to write unit tests ain't such a taboo at all.

I'm in similar situation (assuming Your time is really limited). What i do - i don't think about unit tests most of the time. But for some cases - it's actual easier to do TDD than to continue hacking (emm... duct taping? :D ) everything together (usually when testable unit has high complexity or is hard to test manually), then i just switch my mind and code normally. In short term - i will be able to understand what i wrote month ago and that won't make much trouble. Problems will arise when project will slip into maintenance phase. But it's still way much better than telling client that you worked on tests and got nothing new.

When you need to start unit testing in existing project - start with your own functionality. Create necessary test infrastructure (if time allows - continuous integration too) and don't forget to teach unit testing to your co-workers.

Worst thing you (or PM) can do - to force writing unit tests to someone who does not know how to do that. That's just wasting time. Lead by example. Gradually.


It did start after all! ^_^

Arnis L.
+4  A: 

I had a very similar experience a few years ago, and stumbled upon this book:

Working Effectively With Legacy Code by Michael C. Feathers

It has an incredibly complete set of techniques for starting with an existing codebase that has no unit test coverage, and gradually getting it under test. If I could recommend only one book on TDD, it would be this one.

Hopefully this helps... best of luck!

Tyler

Tyler
That helps, thanks +1 and good luck on SO
Yar