Software and People

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!

It's a long standing tradition, so I felt I had to join in.

I'm Frank Carver. I'm a "sheriff" at javaranch.com, a freelance Java programmer, a teacher at a local college, a father, a contributor to several open source projects, and so on. My definitive "home page" can be found at Frank Carver.

this is my first post in my "JavaRanch Radio" weblog. I'd imagine that future posts will be both occasional and episodic. Some may even be interesting. Don't hold your breath.

Thanks for taking the time to read this, anyway.