I'm a great fan of unit testing, including test-driven development and the practices of Extreme Programming (XP). I try and develop unit tests for all the code I write.
Sometimes, of course, unit testing everything is simply not possible. On a project I'm working on at the moment I don't have access to the machines the final system will be running on, and only a sketchy idea of the input data my code will actually recieve. Sure, I have got a test suite to test that all my code does what I think it should do, but there are inevitably misunderstandings and hiccups when it runs on the real system.
Despite all this, the fault that irritates me most is one that I should, and could, easily have caught in my own testing. The doubly irritating part is that I got part way to detecting the fault before I delivered it, but then just got lazy.
In the example data are some integer timestamps, for example 1077797400. I did a little experiment:
Date timestamp = new Date(1077797400); System.out.println(timestamp);
The system has only been in existence for a few years, so when it printed out Tue Jan 13 12:23:17 GMT 1970 it seemed somewhat unlikely.
I got in touch with my client contact, and he told me that timestamps are stored in seconds, not milliseconds (as used by java.util.Date). "That's easy to fix, I thought. "What can go wrong with simply multiplying by 1000?".
If you are really sharp (or have faced this yourself recently), you should be able to guess the problem, already. Unfortunately, I didn't until I got client complaints about daft dates. My first assumption was that I had simply delivered the wrong code, but when I looked at it, there was my multiplication:
public static Date makeDate(int i)
{
Date ret = new Date(i * 1000);
return ret;
}
So I went back to my test code and added the multiplication, like I should have done in the first place:
Date timestamp = new Date(1077797400 * 1000); System.out.println(timestamp);
It printed out Mon Dec 29 06:30:08 GMT 1969. Multiplying by 1000 had made the same timestamp go back in time
I sure was baffled at the time, but something occurred to me in the middle of the night. First thing when I woke in the morning (well, after having a coffee, eating some breakfast, checking my mail and so on - I'm not that much of a geek) I added a single character to my test code, and got out the much more reasonable Thu Feb 26 12:10:00 GMT 2004.
Figured it out yet?
I added an 'L':
Date timestamp = new Date(1077797400 * 1000L); System.out.println(timestamp);
This forced the calculation into long arithmetic rather than sticking with integers, and allowed the result to increase rather than overflowing and "wrapping round" into a negative number. Once I realized, the answer was obvious and simple.
So, next time, when someone asks that question about "how do I know what I should test?", I'll remember this. Ten seconds of testing would have saved me the embarassment of client complaints after delivery and a restless night. Sounds like a good deal to me!