我是一枚潜藏在数据库引擎深处的Bug,躲在一个黑暗的角落很久了,历经多个版本、N轮回归测试的风雨洗礼,我存在,我骄傲。还记得那天,我怀着激动而忐忑的心情等待一位QA新人把我发布出去……
产品发布在即,一位颇有经验的QA在无意间写了一条短小精悍的用例让QA新人来执行一遍,就是这条不起眼的用例,使我原形毕露。这个用例看起来很简单:就是向数据库里插入一条null记录(还记得我们的Mr Null吗?),一条字符串记录;再一条null记录,一条同样的字符串记录……如此反复,来个5000次,然后启用创建数据字典的功能,将这若干条看似规律的记录进行压缩。好歹咱也算经历过风风雨雨的,每天的持续回归测试也没有拿我怎么样,可就在执行这条小用例时,神奇的事情发生了------数据库发生了崩溃。
原因分析:
这个难题先后困扰过好几个人,直到一位研究“炸弹”的开发GG,他对我进行了好好的剖析,终于发现了问题的缘由。具体要从数据库引擎的压缩机制开始讲起:
● 记录压缩:是基于数据字典的压缩。所谓数据字典,就是数据库表所有记录中出现频率最大的字符串集合。压缩时,将记录中与数据字典相同的字符串进行替换,替换为数据字典的下标。由于数据字典的下标一定会远远小于字典所代表的字符串,因此就达到了记录压缩的效果。
● 实现流程:该引擎的数据字典在采集时,是将所有的记录拼成一条长长的字符串流,然后从字符串流中采集出现频率最高的子串,作为数据字典,而拼接记录时并未在记录间添加分隔符。这种一行null记录、一行字符串记录的方式,会使数据库引擎采集的数据字典的长度超过记录的最大长度,导致系统内部验证报错。
解决办法:
知道了问题的本质,解决起来就很方便了,在将记录拼接为长字符串流时,在每个记录的拼接处添加分隔符。不能跨越分隔符采集数据字典,从而保证了数据字典的长度一定小于等于记录的长度限制,问题解决!
经验总结:
● 注意边界问题。问题往往出现在边界情况下,比如最大值/最小值/0值。如果在代码中加入一些边界断言,可以帮助提早发现问题。
● 注意“null”的使用。不论开发还是测试,注意“null”的使用都可以帮助我们少犯一些错误,或者多发现一些问题。
● “杀虫剂困境”的思考。再严密的单一性测试也不可能发现100%的Bug。将不同的测试思路和方法相结合,采用探索式的测试思维或许能帮助发现更多潜在问题。
说了这么多,我得闭嘴了,不低调的Bug是不厚道的,最后把一句很喜欢的佛语送给大家:“你见,或者不见我,我就在那里”,但是我们始终敌不过开发和测试的协同努力。