设为首页收藏本站

期待广告

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1297|回复: 13
打印 上一主题 下一主题

For Lega——A Bug's Life

[复制链接]
跳转到指定楼层
1#
发表于 2003-11-28 18:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一个原来在华为的同事转来的文章,[奸笑]

在对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、单元测试中,测试用例输出的检查是单元测试中的一个重要环节。如果没有一个有效的输出检查,就算问题被暴露出来,也难以发现。因此,单元测试不应该只追求用例的覆盖度,用例的输出检查同样重要。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享
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、单元测试中,测试用例输出的检查是单元测试中的一个重要环节。如果没有一个有效的输出检查,就算问题被暴露出来,也难以发现。因此,单元测试不应该只追求用例的覆盖度,用例的输出检查同样重要。
回复 支持 反对

使用道具 举报

3#
发表于 2003-11-28 19:18 | 只看该作者

Re: For Lega——A Bug's Life

时日无多,最新工程方法XP极限编程提出以测试为先
没有代码之前先布下天罗地网,虫子何处能跑
[我哭]
回复 支持 反对

使用道具 举报

4#
 楼主| 发表于 2003-11-28 19:47 | 只看该作者

Re: For Lega——A Bug's Life

LEGA要小心喽![奸笑]
回复 支持 反对

使用道具 举报

5#
发表于 2003-11-28 21:17 | 只看该作者

Re: For Lega——A Bug's Life

[吐舌]

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

   for( i = 0; i

  写成了

   for( i = 0; i


看了半天也没有看出任何不同,好像都没有写全不。。。。。。
回复 支持 反对

使用道具 举报

6#
发表于 2003-11-28 21:30 | 只看该作者

Re: For Lega——A Bug's Life

[心仪]一堆虫虫。



回复 支持 反对

使用道具 举报

7#
发表于 2003-11-28 21:31 | 只看该作者

Re: For Lega——A Bug's Life



[心仪]一堆虫虫。
回复 支持 反对

使用道具 举报

8#
发表于 2003-11-28 22:01 | 只看该作者

Re: For Lega——A Bug's Life

精美,选一个做头像
回复 支持 反对

使用道具 举报

9#
发表于 2003-11-28 22:44 | 只看该作者

Re: For Lega——A Bug's Life


再来一个![吐舌]
回复 支持 反对

使用道具 举报

10#
 楼主| 发表于 2003-11-28 23:14 | 只看该作者

Re: For Lega——A Bug's Life

好恐怖。
回复 支持 反对

使用道具 举报

11#
发表于 2003-11-29 11:20 | 只看该作者

Re: For Lega——A Bug's Life

BUG的手脚都被修理掉了!!![惊讶]
回复 支持 反对

使用道具 举报

12#
 楼主| 发表于 2003-11-29 12:44 | 只看该作者

Re: For Lega——A Bug's Life

最初由不会游泳的鱼发表
[吐舌]


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


同事转过来的时候就是这样的。据说错的写法是把;写成:了,不过我们一直疑惑,这样能过得了语法检查吗?
回复 支持 反对

使用道具 举报

13#
发表于 2003-11-29 13:30 | 只看该作者

Re: For Lega——A Bug's Life

for( i == 0; i
回复 支持 反对

使用道具 举报

14#
发表于 2003-11-30 14:49 | 只看该作者

Re: For Lega——A Bug's Life

终于知道:



什么是









天书!
[汗][汗][汗]
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|骏景花园业主论坛 ( 粤ICP备2021144690号-2  

GMT+8, 2025-1-14 03:15 , Processed in 0.071056 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表