Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

If you've always loved unit testing, good for you! But for the unfortunate ones who weren't born with a liking for it, how have you managed to make this task more enjoyable ?

This is not a "what is the right way to unit test" question. I simply want to know little personal tricks that reduce the boredom (dare I say) of writing unit tests.

share|improve this question
1  
I love writing unit tests and other tests partly because just about everyone else kind of sucks at it (sometimes they also suck at making tools that I am testing). No, I do not suck as a developer. I just like usability, eye candy and automation. The MbUnit library has changed my life. Auto testing is important. Auto testing saves time. Auto testing saves money. Auto testing can save lives. Auto testing is the only way. Auto-testing is yet another safety net. When I am one of 50 people working on a huge architecture, I feel like yet another brick in a wall. With unit tests I am in control. –  Job Feb 1 '11 at 4:05
add comment

8 Answers

up vote 16 down vote accepted

Firstly, I agree with you - if you are writing your unit tests on already completed code, or you are manually unit testing your code, I find that extremely boring too.

I find there are two ways of unit testing for me that really make it enjoyable:

  1. By using Test Driven Development (TDD) - writing the tests first allows me to think about the next piece of functionality or behaviour that I need in my code. I find driving towards my end goal in tiny steps and seeing tangible progress towards that goal every few minutes extremely rewarding and enjoyable.
  2. When there are bugs, rather than going straight to the debugger, it's a fun challenge to figure out a way to write a failing unit test that reproduces the bug. It's extremely satisfying to finally figure out the circumstances that make your code fail, then fix it and watch the bar turn green for the new failing test (and stay green for all of your existing tests).
share|improve this answer
2  
I like no. 2 too, it can be fun and your test suite gets stronger by the day! –  Preets Sep 21 '10 at 13:47
    
I am using TDD on a hobby project of mine and I am actually having a lot of fun. (Can't believe I wrote that). –  Preets Sep 30 '10 at 13:45
    
Yay! I'm glad you tried it. –  Paddyslacker Sep 30 '10 at 15:17
    
+1 because you're putting the horse before the cart.:) –  David Dec 29 '10 at 6:09
    
Nitpicking maybe, but case 2) is really a regression test, not a unit-test. –  Nemanja Trifunovic Jan 31 '11 at 21:23
add comment

Smug superiority.

I'm only half-joking. "Look at me, cultivating good programming habits! This 'unit testing' stuff is something Me From Ten Years Ago never would have done -- what a fool! And just think of all the bugs I'm going to catch as a result of this boring, tedious work I'm doing right now -- my code will be awesome! I'll get a raise for sure!*"

* -- No, I won't.

I find it's like working out or eating healthy; until the tangible benefits actually kick in ("Holy balls, I really AM catching a crap-ton of regression errors that would have snuck into production!"), the moral pride of knowing that you're doing The Right Thing can help carry you through.

share|improve this answer
    
:D funny, now when was the last time I ate healthy ? –  Preets Sep 9 '10 at 14:56
    
Hey, I had a salad ... just this week! With green stuff and everything! And more green stuff than dressing! Honest! –  BlairHippo Sep 9 '10 at 15:06
    
The exercise analogy makes me think - people hate regular exercising, which is why we have classes like "Cardio Latin Dances". Now whats the equivalent of dancing your way to a health life in the Unit Testing world ? –  Preets Sep 9 '10 at 15:10
    
Hmm. Now that's a damn fine question. Coming up with little rewards to give yourself when you hit certain milestones? "Good code monkey, have a biscuit!" –  BlairHippo Sep 9 '10 at 18:26
    
Ooh, actually, reading one of your other comments here ... so, debugging is fun to you? Then put yourself in that headspace. You're not unit-testing; you're debugging! Preemptively! You're not testing the code -- you're breaking it. You're finding bugs that are so damn sneaky you don't even know they EXIST yet. –  BlairHippo Sep 9 '10 at 18:29
show 6 more comments

I don't know. What definitely makes unit testing more enjoyable to me is the thought of all the frustrating, lengthy, boring and unrewarding debugging I will not have go through every time I make a change in the software :)

share|improve this answer
2  
That is interesting. Because personally, when someone finds a bug in my code I bury my head in shame, but at the same time, the process of debugging for me is actually quite entertaining and way more fun that unit testing. It is like solving a puzzle where you have to catch that sneaky bug. –  Preets Sep 9 '10 at 15:02
    
@Preets: I agree, sometimes it can be fun, but for me, design is much more interesting than implementation. Thus I don't like to spend much time on implementation. I prefer it to be straight forward and predictable, especially because it allows making more reliable time schedules. As much as I enjoy the process of creating software, I think the result is decisive. –  back2dos Sep 9 '10 at 20:20
    
Oh I completely agree! A system with random bugs can cause sleepless nights.. my choice was simply a preference in an unreal world where nothing other than having fun mattered ! –  Preets Oct 11 '10 at 22:46
add comment

For one, I almost never just sit there and write unit tests. Unit tests are a means to an end, not an end in themselves. They are a way of answering "does this code do the basic task that it is supposed to."

For instance, some people will write a function, and then open an interactive session to test it out on a few values and make sure it's working:

def fact x
  if x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact 10
=> 3628800
>> fact 7
=> 5040

But now you discover a bug:

>> fact -1
SystemStackError: stack level too deep
    from (irb):2:in `fact'
    from (irb):5:in `fact'
    from (irb):10

So you fix it:

def fact x
  if x < 0
    raise "Can't take the factorial of a negative number"
  elsif x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact -1
RuntimeError: Can't take the factorial of a negative number
    from (irb):3:in `fact'
    from (irb):10

But now you really ought to test to make sure it still works:

>> fact 10
=> 3628800
>> fact 7
=> 5040

As you can see, you keep on repeating the same tests... and you have to compare the results visually. Unit testing is a way of avoiding the repetition in this case; it reduces how much work you need to do. And while this is a silly little example, in the real world, it becomes more and more important, and more and more difficult to test manually. What this means, of course, is that people simply don't test the individual components; they just test the whole program. But then bugs crop up, and they're much harder to find. Or bugs happen, and they're fixed, but someone introduces the same bug all over again, because no one added a test case to make sure that didn't happen. Or someone looks at a big piece of code, and says "I have no idea what this is supposed to do, since it's not documented and has no tests... if I fix this bug, I have no idea if I'll break something else depending on it; maybe I'll just rewrite this from scratch."

Unit tests reduce all of the extra work in these cases. The best way to make them fun is to make sure that people understand all of the work that they are replacing, and the extra flexibility that comes from knowing what each piece of code is supposed to do. To some degree, people need to have a bit more experience with writing and maintaining a large code base to understand how important unit testing can be; if all of their code is something they write once and throw away, they'll never quite get it.

And unit tests shouldn't be written after the fact, as an extra chore once you have code that you "know" already works. Unit tests should be written first, or at the very least (since you sometimes forget to write them first) right after writing the code in question. This is called test-driven development, and it can help make your APIs better; if you write the tests that exercise the APIs first, you will learn where the APIs are a pain to use before you even write the code, and can redesign much more easily than if you only add the tests afterwards.

share|improve this answer
    
@Biran, I agree. But all of that makes it the "right" thing to. But how does one make it enjoyable? Even slightly? –  Preets Sep 9 '10 at 15:07
    
@Preets It's enjoyable because you're avoiding doing repetitive manual testing. It's more enjoyable when you do it first, as opposed to after the fact, because it becomes part of the design process, not an after the fact chore for code that already "works." –  Brian Campbell Sep 9 '10 at 15:56
    
So, spend time doing it badly, so that doing it RIGHT feels fun by comparison? ... That might work, actually.... –  BlairHippo Sep 9 '10 at 18:27
    
@Biran, I agree, one must do it "first" - not only to eliminate boredom, but I suppose that IS the right way to do in it order to reap the true benefits of unit testing. –  Preets Sep 14 '10 at 13:57
    
@Biran, Thank you! I recently used TDD on a hobby project of mine and it changed the way I think about unit testing. –  Preets Sep 30 '10 at 13:50
add comment

Obviously, there is the satisfaction of test-first development and the feeling you get when your design and tests come together. However, writing tests for pre-existing/legacy code can be mind-numbing and frustrating. When our project was in a maintenance pattern, I wrote tests for untested code using the coverage report as a game. You can create a bit of a competition with yourself and/or others to boost the coverage numbers. Granted, you might take it too far and create some bad tests, but it can be a good motivator.

share|improve this answer
    
since legacy code is generally not easily testable, I find myself struggling to write good unit tests - so not only is the process painful, but the result (unit tests) aren't particularly useful either :-/ I find that most frustrating... The coverage game is a good one though :) –  Preets Oct 11 '10 at 22:31
add comment

The smug superiority you feel when you check in code that is rock-solid, robust, and stable. And if you write unit tests with a code coverage tool, you can boast in your check in comments that your code coverage is 90% or higher.

share|improve this answer
add comment

Try to get into the Flow. Set tough, but achievable goals to yourself. What could be a goal in unit testing? For example, try to write faster while keeping quality. Unit tests don't require too much thought so mistaking is unlikely. Concentrate on your goal and check often to see as you are nearing it.

share|improve this answer
    
ás, why do you say unit test do not requite too much thought? If you work with TDD it does involve a lot of thinking. Is that not true ? –  Preets Oct 11 '10 at 22:33
    
You are right, I didn't take TDD into account. –  Tamás Szelei Oct 12 '10 at 7:59
add comment

Sometimes to get myself motivated, I'll write down my current "code coverage" at the start of the day. Then each time I write a test and get it to pass, I'll run the suite, and update the coverage number. It's fun, and it helps remind me why I'm doing this. (There are other reasons too, but I like the numbers. Maybe that is just me!)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.