骏景花园业主论坛

标题: For Lega——A Bug's Life [打印本页]

作者: 兴高彩烈    时间: 2003-11-28 18:56
标题: For Lega——A Bug's Life
一个原来在华为的同事转来的文章,[奸笑]

在对XXX版本进行稳定性测试的过程中,发现对一个数据表中的几千条记录在一个事务中删除时,会返回数据不一致的问题。根据经验,数据不一致的问题往往是在同一个事务中对同一条记录修改了两次,或者是在不同单板上同时对一条记录进行了修改。根据现象,后者的可能性不存在,于是,问题的要害就放在了为什么会对同一条记录修改两次这个出发点上。但问题的最终定位并没有想象的这么简单,一会儿单步跟踪,一会儿添加打印,一会儿又走读源代码,整整折腾了一个下午,问题的根源才算找到了,一个非常简单的错误,在一个for循环中将循环条件

   for( i = 0; i

  写成了

   for( i = 0; i

  这么一个简单的错误,居然让一个开发人员和一个测试人员折腾了这么长时间,看来有些问题是需要我们静下心来,仔细地考虑一下了。为什么这样一个问题,从代码完成到最终发现,几乎一年的时间,在这段时间里,有多次机会可以将其逮住就地正法,但都被它从容地逃过了呢?让我们来分析一下这个bug的一生吧,也许会给我们一点启示。

  在开发人员手起键落中,这个bug诞生了。这时候,它很弱小,只要开发人员回过头来再稍微检查一下,它就会被检查出来,比碾死一只蚂蚁更加简单。但是,开发人员没有回过头来,因为前面还有海量的代码等着他,他今天已经写了上百行的代码,现在所有的代码在他眼里都已经只是符号而已,他脑子里只有两个字——"进度"。当开发者开始下一个函数的编写时,这个bug兴奋地跑进了遍布着自己同伴的代码堆中,它知道,只要进了这个庇护所,它就安全了,这里不但地形复杂,而且同伴众多,可以给它充分的掩护。但同伴告诉它,逃生没这么简单,因为每天还有一次叫做"走读"的东东,在等着它们,它的很多同伴就是丧生在这个厉害的家伙手里。当这个bug提心吊胆地等着"走读"这个杀手出现的时候,它听说了一个意外的好消息,由于进度紧张,走读被取消了,说等到代码全部完成后再进行。对于bug们来说,这实在是个好消息,因为这样又可以多活一个多月了。

  bug在代码堆里舒舒服服地躺了一个多月,看着代码堆越来越大,同伴越来越多,心里乐开了花。但此时,残酷的屠杀——"单元测试"开始了,同伴们被一个一个揪了出去,它整天战战兢兢怕蹈了同伴们的覆辙。终于有一天,它藏身的函数被扫荡到了。只见几个测试用例凶猛地冲了进来,三下五除二就将几个隐藏不深的同伴给抓走了。没过多久,一个测试用例就使自己暴露了出来,这只bug闭上了眼睛,它知道自己死定了。当它再次睁开眼睛的时候,连自己都不敢相信,自己居然还活着。在庆幸之余,它仔细地反省了自己能够活下来的原因。原来,只有当同时查询超过1024条记录时,自己才会非常隐蔽地暴露出来,而开发人员设计的测试用例,根本就没有自动检查测试输出的功能,而通过肉眼在上千条记录中发现有什么异常,简直是天方夜谭。经过这样的分析,这个bug认为自己基本上可以高枕无忧了。因为超过上千条记录的查询本来就少,就算被查出来,也没有人仔细地检查查询结果。

  经过了"单元测试"的扫荡,接下来是更加残酷的"集成测试"了。在集成测试的过程中,还搀杂着大量的bug杀手——"走读"。对于bug来说,这简直是雪上加霜,尤其是一帮新员工的走读,更是歹毒。这帮新员工虽然什么都不懂,但初生牛犊不怕虎,有一股特有的认真劲。看着一大批隐藏很深的同伴被一一抓走,这个bug也很心虚,直到有一天,它听说自己所在的函数由于经常被运行并且比较稳定,将不在走读的目标中,走读的重点是那些比较不稳定的函数时,它才放了心。

  在集成测试的扫荡中,这个bug心里一直还有一个隐患,那就是对大量的记录修改和删除之前,会先进行查询,而这样的操作会让自己暴露得一览无遗。幸好,由于代码设计上的问题,对大量记录同时操作会导致内存申请不到,于是开发人员一般建议大家不要对大量记录进行一次性操作,有了这道"圣旨",简直是有了免死金牌,bug终于可以高枕无忧了。

  经过了一道道的测试,同伴们已经所剩无几了,但这个bug依然无忧无虑。因为它知道,按目前的这种测试,它可以安然地到达客户手中。到那时,哈哈,那就是它的天下了,它随便勾勾小指头,就够开发人员忙活半天的,还得点头哈腰向客户道歉。哼,叫你们抓我抓得这么紧,有你们的好看。想到这儿,bug在梦中都能笑醒过来。

  但这个bug没有想到的是,它的美梦被一个新来的测试人员给打破了。正是因为他对代码不是很了解,所以他百无禁忌,对于不能大量操作记录的"圣旨"置之不理。正是因为他的负责,任何问题他都追究到底,非要开发人员彻底解决不可。结果,经过一个下午的折腾,终于将这个bug彻底给挖了出来。

  bug给抓出来了,但是我们在开发过程中,一次次让bug溜走的教训却值得我们反思,针对这个bug的一生,在开发中,我们要注意点什么呢?

  1、开发人员在代码编写过程中要做到时刻检查,不要等到代码写了一大堆后再检查,一些逻辑判断可以取两个一般值、一个边界值代进去先验证一下,能在编码阶段发现的问题,就不要等到单元测试。这样写代码的速度虽然慢一点,但留到单元测试的问题就会少很多,单元测试的时候,边发现问题边改代码,可能还要重新插桩,花费的时间要远远超过自己写代码时候检查的时间。

  2、单元测试中,测试用例输出的检查是单元测试中的一个重要环节。如果没有一个有效的输出检查,就算问题被暴露出来,也难以发现。因此,单元测试不应该只追求用例的覆盖度,用例的输出检查同样重要。

作者: 兴高彩烈    时间: 2003-11-28 18:57
标题: Re: For Lega——A Bug's Life
  在开发人员手起键落中,这个[RED]LEGA[/RED]诞生了。这时候,它很弱小,只要开发人员回过头来再稍微检查一下,它就会被检查出来,比碾死一只蚂蚁更加简单。但是,开发人员没有回过头来,因为前面还有海量的代码等着他,他今天已经写了上百行的代码,现在所有的代码在他眼里都已经只是符号而已,他脑子里只有两个字——"进度"。当开发者开始下一个函数的编写时,这个[RED]LEGA[/RED]兴奋地跑进了遍布着自己同伴的代码堆中,它知道,只要进了这个庇护所,它就安全了,这里不但地形复杂,而且同伴众多,可以给它充分的掩护。但同伴告诉它,逃生没这么简单,因为每天还有一次叫做"走读"的东东,在等着它们,它的很多同伴就是丧生在这个厉害的家伙手里。当这个[RED]LEGA[/RED]提心吊胆地等着"走读"这个杀手出现的时候,它听说了一个意外的好消息,由于进度紧张,走读被取消了,说等到代码全部完成后再进行。对于[RED]LEGA[/RED]们来说,这实在是个好消息,因为这样又可以多活一个多月了。

  [RED]LEGA[/RED]在代码堆里舒舒服服地躺了一个多月,看着代码堆越来越大,同伴越来越多,心里乐开了花。但此时,残酷的屠杀——"单元测试"开始了,同伴们被一个一个揪了出去,它整天战战兢兢怕蹈了同伴们的覆辙。终于有一天,它藏身的函数被扫荡到了。只见几个测试用例凶猛地冲了进来,三下五除二就将几个隐藏不深的同伴给抓走了。没过多久,一个测试用例就使自己暴露了出来,这只[RED]LEGA[/RED]闭上了眼睛,它知道自己死定了。当它再次睁开眼睛的时候,连自己都不敢相信,自己居然还活着。在庆幸之余,它仔细地反省了自己能够活下来的原因。原来,只有当同时查询超过1024条记录时,自己才会非常隐蔽地暴露出来,而开发人员设计的测试用例,根本就没有自动检查测试输出的功能,而通过肉眼在上千条记录中发现有什么异常,简直是天方夜谭。经过这样的分析,这个[RED]LEGA[/RED]认为自己基本上可以高枕无忧了。因为超过上千条记录的查询本来就少,就算被查出来,也没有人仔细地检查查询结果。

  经过了"单元测试"的扫荡,接下来是更加残酷的"集成测试"了。在集成测试的过程中,还搀杂着大量的[RED]LEGA[/RED]杀手——"走读"。对于[RED]LEGA[/RED]来说,这简直是雪上加霜,尤其是一帮新员工的走读,更是歹毒。这帮新员工虽然什么都不懂,但初生牛犊不怕虎,有一股特有的认真劲。看着一大批隐藏很深的同伴被一一抓走,这个[RED]LEGA[/RED]也很心虚,直到有一天,它听说自己所在的函数由于经常被运行并且比较稳定,将不在走读的目标中,走读的重点是那些比较不稳定的函数时,它才放了心。

  在集成测试的扫荡中,这个[RED]LEGA[/RED]心里一直还有一个隐患,那就是对大量的记录修改和删除之前,会先进行查询,而这样的操作会让自己暴露得一览无遗。幸好,由于代码设计上的问题,对大量记录同时操作会导致内存申请不到,于是开发人员一般建议大家不要对大量记录进行一次性操作,有了这道"圣旨",简直是有了免死金牌,[RED]LEGA[/RED]终于可以高枕无忧了。

  经过了一道道的测试,同伴们已经所剩无几了,但这个[RED]LEGA[/RED]依然无忧无虑。因为它知道,按目前的这种测试,它可以安然地到达客户手中。到那时,哈哈,那就是它的天下了,它随便勾勾小指头,就够开发人员忙活半天的,还得点头哈腰向客户道歉。哼,叫你们抓我抓得这么紧,有你们的好看。想到这儿,[RED]LEGA[/RED]在梦中都能笑醒过来。

  但这个[RED]LEGA[/RED]没有想到的是,它的美梦被一个新来的测试人员给打破了。正是因为他对代码不是很了解,所以他百无禁忌,对于不能大量操作记录的"圣旨"置之不理。正是因为他的负责,任何问题他都追究到底,非要开发人员彻底解决不可。结果,经过一个下午的折腾,终于将这个[RED]LEGA[/RED]彻底给挖了出来。

  [RED]LEGA[/RED]给抓出来了,但是我们在开发过程中,一次次让[RED]LEGA[/RED]溜走的教训却值得我们反思,针对这个[RED]LEGA[/RED]的一生,在开发中,我们要注意点什么呢?

  1、开发人员在代码编写过程中要做到时刻检查,不要等到代码写了一大堆后再检查,一些逻辑判断可以取两个一般值、一个边界值代进去先验证一下,能在编码阶段发现的问题,就不要等到单元测试。这样写代码的速度虽然慢一点,但留到单元测试的问题就会少很多,单元测试的时候,边发现问题边改代码,可能还要重新插桩,花费的时间要远远超过自己写代码时候检查的时间。

  2、单元测试中,测试用例输出的检查是单元测试中的一个重要环节。如果没有一个有效的输出检查,就算问题被暴露出来,也难以发现。因此,单元测试不应该只追求用例的覆盖度,用例的输出检查同样重要。

作者: lega    时间: 2003-11-28 19:18
标题: Re: For Lega——A Bug's Life
时日无多,最新工程方法XP极限编程提出以测试为先
没有代码之前先布下天罗地网,虫子何处能跑
[我哭]
作者: 兴高彩烈    时间: 2003-11-28 19:47
标题: Re: For Lega——A Bug's Life
LEGA要小心喽![奸笑]
作者: 不会游泳的鱼    时间: 2003-11-28 21:17
标题: Re: For Lega——A Bug's Life
[吐舌]

在一个for循环中将循环条件

   for( i = 0; i

  写成了

   for( i = 0; i


看了半天也没有看出任何不同,好像都没有写全不。。。。。。

作者: 不会游泳的鱼    时间: 2003-11-28 21:30
标题: Re: For Lega——A Bug's Life
[心仪]一堆虫虫。




作者: 不会游泳的鱼    时间: 2003-11-28 21:31
标题: Re: For Lega——A Bug's Life


[心仪]一堆虫虫。

作者: lega    时间: 2003-11-28 22:01
标题: Re: For Lega——A Bug's Life
精美,选一个做头像
作者: 不会游泳的鱼    时间: 2003-11-28 22:44
标题: Re: For Lega——A Bug's Life

再来一个![吐舌]

作者: 兴高彩烈    时间: 2003-11-28 23:14
标题: Re: For Lega——A Bug's Life
好恐怖。
作者: peter    时间: 2003-11-29 11:20
标题: Re: For Lega——A Bug's Life
BUG的手脚都被修理掉了!!![惊讶]
作者: 兴高彩烈    时间: 2003-11-29 12:44
标题: Re: For Lega——A Bug's Life
最初由不会游泳的鱼发表
[吐舌]


看了半天也没有看出任何不同,好像都没有写全不。。。。。。


同事转过来的时候就是这样的。据说错的写法是把;写成:了,不过我们一直疑惑,这样能过得了语法检查吗?
作者: lega    时间: 2003-11-29 13:30
标题: Re: For Lega——A Bug's Life
for( i == 0; i
作者: jjean    时间: 2003-11-30 14:49
标题: Re: For Lega——A Bug's Life
终于知道:



什么是









天书!
[汗][汗][汗]




欢迎光临 骏景花园业主论坛 (http://120.76.133.63/forum/) Powered by Discuz! X3.2