yonkeltron.com

Temporary exile

Trouble Testing Timestamps

Since I’ve been encouraging myself to write more and better unit tests, I have encountered a troubling obstacle when writing tests to cover timestamp creation and updating. Let’s say I have a Record class which has a modification and creation timestamp. The ctime instance variable is created when a Record is instatiated and mtime is updated whenever the Record is updated. So, my test looks like this:

def test_ctime
  record = Record.new
  assert_equal(Time.now, record.ctime)
end

This failed because, believe it or not, the timers have too high a resolution! In fact, even evaluating (with the help of irb) Time.now == Time.now is false. This is evident by evaluating 5.times { puts Time.now.to_f } and seeing how the output differs by a tiny amount with each iteration. I response to this, I decided to generalize and adapt my assertion to accept a diminished resolution with a tolerance of one second. assert_equal(Time.now.sec, record.ctime.to_i). This is still imprecise but it gets my point across. I had resigned myself to accept this troublesome compromise until I went to write the test for mtime. My test for mtime updating looked like this:

def test_mtime_update
  record = Record.new
  record.update
  assert_operator(Time.now, :>, record.mtime)
end

I feel like I am compromising because I can’t make accurate comparisons and can’t figure out how to do this properly. It seems impossible and I don’t feel as if I have adequate coverage because I can’t verify timestampt at all. Perhaps I am doing something obviously wrong or testing for the wrong things. To make myself feel better I added an assert_instance_of(Time, record.ctime) and the same thing for mtime. Still, this has given me much frustration and I can’t imagine no one else has encountered this before. I’m writing this as part of a multithreaded application where timestamp resolution could be quite crucial and I see my tests failing to give me proper coverage. Help?