有一天,客户反馈了一个奇怪的问题:他们的系统上午、下午都是正常的,但是在中午的时候,数据就无法保存,总是提示“保存失败”,我们接到问题的第一个反应通常是:中午的网络或服务器出现故障导致无法保存,但事实上这个答复客户是不满意的,因为做为一个业务操作系统的网络和服务器不会总是在中午出问题,况且只是“保存失败”,查询的功能都可以使用,这说明客户端和数据库的连接是正常的。
这现象有些怪异,客户的数据库异常日志中报出“字段长度被截断”的记录,但究竟是哪个字段只会在中午被截断呢?我们反复在测试环境中模拟,都没有出现类似的现象,有些一筹莫展,以至于都怀疑是客户的电脑神经了。
但是问题一直是存在的,客户中午都不能正常做业务,情绪越来越大,于是我不得不重新配了一套新的测试环境,和客户的真实环境基本相仿。说来也怪,到中午的时候,现象真的出现了,因为是在开发环境中出现的,我们很容易跟踪到了被截断的字段,是一个时间控件。本来,如果使用数据库的日期时间类型,所有的时间字段都不会出错的。但数据库设计者为了查询的方便用了字符型,10位字符,按常理来说足够了,为什么出了长度溢出的错误呢?
后来我想起这个问题出在操作系统上,我们刚开始的测试环境用的是中文版本的Windows2000,中文操作系统默认的时间格式如“10:10:10”,是八位。但是,我们的客户是一家做国际业务的公司,统一使用英文版本的Windows2000,而英文操作系统默认的时间格式是英国的12小时制表示方法如“10:10:10 AM”,加上空格有11位,而11位的情况只在10、11、12点这三个时间会出现,如果是“9:10:10 AM”,刚好是十位。这也正是只有在中午才会保存失败的真正原因。如果在控制面板中把时间的格式调回24小时制的,这个问题不用改就解决了。但是想到客户的每台客户端都要去调这个格式,我们还是升级了数据库,把字段长度放到12位,彻底解决此问题。
这个问题出现后,我想起来以前读到过的一个“Impossible=I'm possible!”的小故事,这个故事印象深刻,大意是这样的:有一天美国通用汽车公司的庞帝雅克(Pontiac)部门收到一封客户抱怨信,上面是这样写的:“这是我为了同一件事第二次写信给你,我不会怪你们为什么没有回信给我,因为我也觉得这样别人会认为我疯了,但这的确是一个事实。 “我们家有一个传统的习惯,就是我们每天在吃完晚餐后,都会以冰淇淋来当我们的饭后甜点。由于冰淇淋的口味很多,所以我们家每天在饭后才投票决定要吃哪一种口味,等大家决定后我就开车去买。”“但自从最近我买了一部新的庞帝雅克后,在我去买冰淇淋的这段路程问题就发生了。“你知道吗?每当我买的冰淇淋是香草口味时,我从店里出来车子就发不动。但如果我买的是其他的口味,车子发动就顺得很。我要让你知道,我对这件事情是非常认真的,尽管这个问题听起来很猪头。“为什么这部庞帝雅克当我买了香草冰淇淋它就秀逗,而我不管什么时候买其它口味的冰淇淋,它就一尾活龙?为什么?为什么?”
事实上庞帝雅克的总经理对这封信还真的心存怀疑,但他还是派了一位工程师去查看究竟。当工程师去找这位仁兄时,很惊讶的发现这封信是出之于一位事业成功、乐观、且受了高等教育的人。
工程师安排与这位仁兄的见面时间刚好是在用完晚餐的时间,两人于是一个箭步跃上车,往冰淇淋店开去。那个晚上投票结果是香草口味,当买好香草冰淇淋回到车上后,车子又秀逗了。
这位工程师之后又依约来了三个晚上。
第一晚,巧克力冰淇淋,车子没事。
第二晚,草莓冰淇淋,车子也没事。
第三晚,香草冰淇淋,车子“秀逗”。
这位思考有逻辑的工程师,到目前还是死不相信这位仁兄的车子对香草过敏。因此,他仍然不放弃继续安排相同的行程,希望能够将这个问题解决。工程师开始记下从头到现在所发生的种种详细资料,如时间、车子使用油的种类、车子开出及开回的时间……,根据资料显示他有了一个结论,这位仁兄买香草冰淇淋所花的时间比其它口味的要少。为什么呢?
原因是出在这家冰淇淋店的内部设置的问题。因为,香草冰淇淋是所有冰淇淋口味中最畅销的口味,店家为了让顾客每次都能很快的取拿,将香草口味特别分开陈列在单独的冰柜,并将冰柜放置在店的前端;至于其它口味则放置在距离收银台较远的后端。
现在,工程师所要知道的疑问是,为什么这部车会因为从熄火到重新激活的时间较短时就会秀逗?原因很清楚,绝对不是因为香草冰淇淋的关系,工程师很快地由心中浮现出,答案应该是“蒸气锁”。因为当这位仁兄买其它口味时,由于时间较久,引擎有足够的时间散热,重新发动时就没有太大的问题。但是买香草口味时,由于花的时间较短,引擎太热以至于还无法让“蒸气锁”有足够的散热时间。
即使有些问题看起来真的是疯狂,但有时候它还是真的存在;做为一个测试者,我们每次在看待任何问题都要秉持着宽量的思考并去寻找寻解决的方法,碰到问题时模拟不出现象时不要直接就说那是不可能的,而更应投入一些真诚的努力。而我从遇到那个问题以后,再次遇到在客户反馈回问题而测试环境中无法遇到的现象时,不再以“测试没有发现”为解决的理由,而是会进一步去搭建尽量接近真实操作环境的测试环境或者去客户现场看一看,因此抓住了不少隐蔽的BUG。