`
阿尔萨斯
  • 浏览: 4137187 次
社区版块
存档分类
最新评论

思维的陷阱

 
阅读更多

最近在做接口测试的时候遇到一个不算太大的问题,但却值得深思,先说说问题的背景,还有我一步步修复这个问题的过程。

大家都知道,当应用程序对数据库进行写操作的同时往往都会记录下最后一次写操作的时间,有时候我们需要对这个时间进行检查,既检查我执行了写操作以后,我期望的时间字段被更新为当前时间。好像很简单嘛,既然期望他是当前时间,那我就判断查询到的时间是不是当前时间就好了,于是:

private void checkCurrentTime(Date date){

Date now = new Date();

Assert.assertEquals(now, date);

}

毫无疑问,这样是绝对错误的,为什么?因为当你调用这个方法判断某个时间是不是当前时间的时候,其实它已经不是当前时间了,因为它已经过去了,尽管可能只有毫秒级的误差,程序判断不像人那样智能,它是精确的,稍有差别也是错误,所以用这个方法判断显然是不行的。好吧,那么改改,我给它一个误差范围:

private void checkCurrentTime(Date date){

Date now = new Date();

Assert.assertTrue(date.before(now)

&& now.getTime() - date.getTime() < 5000);

}

嗯……这样应该没什么问题了,先解释下,这里判断了两个条件:首先,我要检查我需要判断的时间是在真正的当前时间之前的;其次,我规定它们的误差应该在5秒以内(5秒钟已经很长了,什么事情也应该能做完了,当时我是这么想的)。的确,在理想情况下这样的判断似乎没什么问题,然而,情况通常都是不怎么理想的。经过这样的改变以后,开始几天每天运行都没问题,可是,突然有一天,关于当前时间判断的测试全部都挂掉了,这怎么可能?没道理啊,开发也没有改动过相关的代码,这些测试代码也没有人改过,what happened?经过调试,最后发现,原来是因为数据库的服务器时间有问题,比正确的时间早了大概有七八分钟,问题终于找到了,幸好不是程序本身的问题,好吧,下点血本,把误差时间调大一点——十分钟!这下好了,所有测试又都可以跑通了,我想这下总应该不会出问题了吧。

的确,在相当长的一段时间里,这个判断方法工作良好,但是,我还是要说但是,突然有一天,它们又都挂掉了(是不是很耳熟?),真是没天理啊,用不着反复折磨我吧!没办法,调试吧,结果却让我哭笑不得。还是服务器时间的问题,这次不是又因为超出了误差范围而挂掉的,相反,要检查的时间和真正的当前时间误差只有几秒钟,那为什么会挂掉呢?因为它:date.before(now),这里判断被检查的时间一定要早于当前时间,上面提到了服务器的时间是可能和真实的时间有误差的,可谁也不能规定服务器时间的误差就一定要是早于正确时间的啊!于是我又改进了一下检查当前时间的方法:

private void checkCurrentTime(Date date){

Date now = new Date();

Assert.assertTrue(Math.abs(now.getTime() - date.getTime()) <= 600000);

}

这里就只检查两个时间差的绝对值在规定的范围内了,应该不会再有什么漏洞了吧……

虽然只是一个小小的时间判断方法,然而令我没想到的是它涉及的因素是如此多,细细想想这个方法改进的过程,我不禁冒出一丝冷汗,到底在我们的测试中还有没有类似的隐患存在?原本看似合情合理的判断,却会因为某些没有预料到的外部错误而变得不堪一击,甚至有些滑稽。这都是因为我们平时思考问题的方式太过正常化了,所以才会被所谓的常规思维一步一步导向错误,看来作为测试人员,还真的是要时刻提醒自己——我应该是不正常的!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics