首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

编程高手通天塔:改bug的智慧(一)望文知义

看似没有什么营养的bug描述里,其实蕴含着两个关键要素,往往被我们忽略。开发者一旦掌握了这两个要素,灵感会被瞬间激发出来,立刻想到解决方案,而且是正确的方案!笔者之所以要在这里强调“正确的方案”,原因就在下边对这两个要素的讲述之中。

【一个要素是条件】

Bug描述里一般会列出这些条件:操作系统的版本号,环境变量配置了什么值(这些变量也许会是一个长长的列表),发生bug之前做了什么操作(这些操作也许会是一个长长的列表)。

我们需要从这个描述中找出导致bug的“条件要素”,才能更好的理解bug发生的原因,从而可以找到解决方案。这里提到的“条件要素”是指,如果不执行某个测试步骤,就不会发生这个bug,那么这个步骤就是“条件要素”。

对于能够100%重现bug(或叫必现),我们既可以用下边的方法去找“条件要素”,又可以直接用设置断点的方式去发现代码错误,不过设置哪个断点也有很多可讨论的地方,这些复杂的讨论需要在开发者“做bug重现”时再去解决(参见后续文章)。在这两种方法的具体选择上,要看哪个方法更快、自己更熟悉等因素。

对于重现概率较低的bug,作为一个开发者,如何在这些海量信息面前,迅速找出那个决定性的条件?这绝对是个能力,而且有时很像智商测试题。这是程序员必备的技能,具体的方法有很多,其中一个方法是“对比”。

现代版的俗话说:“没有对比就没有伤害”。

当开发者或测试者修改了某一个测试步骤,例如改变了一个环境变量的值、减少了一个测试步骤、改变了两个测试步骤的顺序,等等,有时就会发现bug没有了,那就证明是这次的测试步骤改变导致bug消失的,条件要素也就找到了。

这里有两个变化需要注意:

一、无论是必现的bug还是不必现的bug,修改一个步骤后bug消失了,一般情况下就能判断出是这次修改步骤导致的,但仅限于一般情况,还有其他情况导致bug发生,例如多线程,这些复杂的讨论需要在开发者“做bug重现”时再去解决(参见后续文章),这个阶段只是为了让项目经理、开发者、测试者看懂bug就足够做决策用了。

二、一次只能改变一个测试步骤,否则我们就无法准确知道是哪个改变导致的。

到此为止,方法是有了,但是方法还不够有力。一旦测试步骤非常多,那么需要对比的测试用例就多,有时会达到100条以上,这样的效率就太低了,而且操作起来让人心烦,根本找不到工作中的快乐。

好在我们还有更好的方法:谷歌搜索的“手气不错”!也就是说,在把所有情况罗列出来以前,先用自己的直觉试验一个最有可能的用例,往往就能找到那个关键的条件要素。不过直觉需要知识和经验的积累,更需要对经验的“反刍”。

【另一个要素是“错误是什么”】

有人会说,“错误是什么”不是明摆着的吗?看完下边这个例子,他就能体会到“明摆着”只是一种奢望:

有一个Bug的标题是:用户打开某个界面时,得到的人员列表不符合预期。

Bug的细节描述是:当用户打开应用程序的一个界面时,得到了一个如下这个不符合预期的人员列表:

002 B先生

003 C小姐

001 A先生

而期望值是:

001 A先生

002 B先生

003 C小姐

理解错误的坏结果

如果这个列表比较长,那么靠人眼去对比期望值和实际结果,需要多花一点时间。不要小看多花的这一点时间,一方面,人的大脑看到琐碎的东西一定会比较累。

另一方面,如果是产品经理或项目经理在看这个列表,他不可能去看每一个bug的细节,因为他需要站在一个更高的视角去看待整个项目。所以他看到这种模糊不清的问题,要么多花一些时间去仔细理解这个bug,要么是认为自己理解清楚了,从而让这个bug在整个开发链条中的多个人之间流转一圈,最后bug仍然没有解决,这样一来,多花的时间就有些可观了。

导致理解错误的浅层原因

下面就是一个导致bug无效流转的“坑”。

开发者看到这个结果对比的直觉是:一定是第一列的显示顺序错了。之后,开发者就去改代码,改完之后,测试者又发现了另外一个bug:

当用户打开应用程序的一个界面时,得到了一个如下列表:

001 A先生

002 B先生

003 C小姐

004 A小姐

而期望值是:

001 A先生

004 A小姐

002 B先生

003 C小姐

实际上只是因为在这个列表中又加入一条数据而已,却触发了开发者改上一个bug时的理解错误,导致修改bug的成本翻倍。

经过分析,终于得出结论:应该按照第二列排序,而不是第一列!

这还只是一个最简单的例子,大部分人还是能一眼就能看出来,但是,实际的工作中远比这个情况复杂,想不“中招”就需要去芜取精的能力了。

正确的做法是:

开发者看到这个问题,如果逻辑清晰的话,应该能想到有很多种情况导致这种错误,上文提到的只是其中的两种情况,他想到之后要去找测试者确认,有时甚至要找到需求文档编写者和产品经理。

导致理解错误的深层原因

表面上看起来这是个沟通问题,其实不是,这是因为:测试者确切地知道需求是什么,只是他认为没必要写出来,而开发者也认为自己理解对了,也就没必要再问,导致了bug的无效流转。当大家都认为没有分歧时,自然就不需要沟通,所以逻辑能力的欠缺才是深层原因!

解决逻辑能力欠缺的有效方法有两个:长期来看,应该去学习、思考。短期来看,用最准确的语言去描述,例如上文的bug描述应改为:用户打开某个界面时,得到的人员列表应该按照第二列排序。

导致理解错误的知识原因

行文至此,如果读者认为这就是“第二个要素:错误是什么”的全部了,“也不过如此嘛”,那有时还会掉到下边这个更深的“坑”里:

对于使用分布式数据库的系统,程序中传给数据库的SQL中,如果没有包含order by,那得到数据的顺序是不会得到保证的!因为分布式数据库为了提高性能,是用并发的方式从多个数据库节点获得数据,既然是并发,那就无法确定哪个节点的数据先传到。

如果开发者没有这个知识,或即便有这个知识而忘记了在这里运用它,就会掉到上边这个“深坑”里。结果就是:让一个bug衍生出另外一个bug,再衍生出第三个bug,让这些“臭虫”在开发者、测试者、项目经理、产品经理,甚至客户那里转啊转,创造出的GDP是很多了,但都是无价值甚至是负价值的GDP。

作于2018-3-10

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180411G1S8FW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券