如何有效报告 bug
前言
身为一个有追求、有修养的程序员,除了要能解决 bug,也需要懂得如何有效的报告 bug。本篇文章主要内容来自于一篇英文博客,我翻译之后又做了些加工,英文好的朋友也可以直接去读 原文 https://link.jianshu.com/?t=https://www.chiark.greenend.org.uk/~sgtatham/bugs.html。
概述
写过开源软件的人,大都收到过至少一个很糟糕的 bug 报告,例如
直接说软件不好用
报告的内容毫无意义
没有提供足够的信息
给出了错误的信息
问题是由于用户的过失产生的
问题是由于其他程序的错误而产生的
问题是由于网络错误而产生的
这也是「技术支持」被视为一个可怕工作的原因。然而,并不是所有的 bug 报告都是让人不愉快的。我一直在没赚钱的时候维护开源软件,有时候会收到一些非常清晰的、有帮助的、内容丰富的 bug 报告。
在这篇文章中,我将尽量说清楚如何去写一个好的 bug 报告。我非常希望所有人在报告一个 bug 给其他人之前先看看这篇文章。当然我也希望其他人在给我提 bug 之前已经阅读过这篇文章。
简单地说,报告 bug 的目的是为了让程序员看到程序的错误。你可以亲自示范,也可以给出能够「重现程序错误」的详细、具体的操作说明。如果程序真的出错了,程序员将会试着收集额外信息直到找到错误的原因。如果程序并没有出错,他们可能会让你继续收集更多的信息给他们。
在 bug 报告中,要弄清楚事实(“ 我在电脑上出现了这个问题 ”)和猜测(“ 我觉得这个错误应该是... ”)的区别,如果你愿意的话,可以省略猜测,但千万不要省略事实。
当你在报告 bug 的时候,一定是希望 bug 能够得到修复。所以针对程序员的不好的言语(甚至谩骂)都是没意义的。bug 的产生可能是他们的错,也可能是你自己的问题,或许你有权利对他们发火,但是如果你给他们提供更多有用信息的话,bug 可能会修复的更快。而且请记住:如果软件是免费的话,作者提供了这个软件已经是出于好心,如果太多人对他们无礼的话,他们可能就要收回这种好心了。
一、程序不好用
程序员并不是弱智,如果程序真的一点都不好用的话,他们不可能没有察觉到。既然他们没有察觉到,那肯定是因为程序对于他们是有帮助的。因此,可能是因为你的操作跟他们不一样,或者你的环境跟他们不一样。他们需要更多的信息,提供这些信息是 bug 报告的主要目的。信息总是越多越好。
很多程序,特别是开源程序,会提供一个「已知 bug 的列表」,如果你发现这个 bug 在列表里面有的话,那你有必要好好阅读一下,没必要再报告一次这个 bug,但是如果你觉得你掌握了比这个 bug 列表更多信息的话,那你一定要与程序员进行联系,如果你提供了一些他们之前没有掌握的信息的话,他们将会更容易地修改这些 bug.
这篇文章谈的都是一些指导指南,并不是说他们就一定是要严格恪守的。不同的程序员喜欢不同的 bug 报告方式。如果程序里面附带了自己的 bug 报告指南的话,请好好阅读他们。如果程序中的指导指南与本文中的指导指南有矛盾的话,请遵循程序中附带的指导指南!
如果你不是报告 bug,而是想要寻求帮助的话,你应该说明你曾经到哪寻找问题的答案(例如,“ 我看了第四章和第五章第二节,但是找不到解决问题的方法 ”),这会让程序员知道人们期望找到答案的地方,然后他们能让文档变得更加容易使用。
二、演示给我看
报告 bug 的最好方式之一就是演示给程序员看。让他们站在你的电脑前面,运行他们的程序,然后演示出错的地方。让他们看你是如何启动机器、运行软件、操作软件、以及程序对于你的输入所作出的反应。
他们对于自己写的软件很了解,知道哪些部分很安全,知道哪些可能会出现问题。他们本能知道应该注意些什么。在程序真的出错之前,他们可能已经察觉到不对劲的地方,这些都会给他们一些线索。他们能观察在测试运行期间电脑做的每一件事,然后挑选出他们认为有用的信息。
这可能还不够。也许他们会觉得需要更多的信息,然后让你重新演示一遍。他们可能会在这期间跟你交流一下,以便在他们需要的时候能够重现 bug. 他们可能会试着改变一些操作,以查看问题是个别问题还是一类的问题。如果你比较不走运的话,他们可能会坐下来几个小时,拿出一整套开发工具,好好的研究这个问题。但是最重要的是在程序出错的时候让程序员就在电脑旁。一旦他们看到问题发生,他们通常可以找到问题所在并开始尝试解决他们。
三、告诉我该怎么做
现在是网络时代,是信息交流的时代,是我们能够点击按钮发送软件给俄罗斯朋友的时代,而且他们也能够很方便地评价这个软件。但是如果他发现我的软件存在问题的话,我不可能在他旁边。「演示」是一个很好的方法,但是很多时候都做不到。
如果你必须报告这个 bug,但是程序员又不在现场的话,那你就要想办法重现这个问题,当他们亲眼看到这个问题发生的时候,他们就会处理它了。
所以,你要告诉他们你做了什么。如果是一个图形程序,那你需要告诉他们你所点击的按钮,以及你点击它们的顺序。如果是一个命令行程序的话,请精确地告诉他们你输入了什么命令。除此之外,你还应该尽可能详细地提供你输入的命令以及计算机输出的响应。
把你能想到的所有输入的方式告诉程序员。如果程序需要读取一个文件的话,你可能需要发送文件的副本给他们。如果程序是需要跟另外一台电脑进行网络通信的话,你可能无法发送电脑的副本给他们,但是你至少需要告诉他们电脑的型号,以及安装的软件。
四、我这里很正常啊,哪里出错了?
如果你给程序员提供了很长的输入和操作列表,然后他们运行了自己的程序副本之后并没有发现问题,很有可能是你没有提供足够的信息。可能这个错误不会出现在每一台电脑上面,你的电脑系统可能和他们的电脑在某些方面不一样。也有可能是你误解了程序怎样显示才是对的,例如你们可能看着同样的显示,但是你觉得这是有问题的,但是程序员却认为是正确的。
所以也要描述究竟发生了什么,告诉他们你看到了什么东西以及为什么你觉得你看到的东西是错误的。最好再告诉他们你希望看到的结果是什么。如果你只是说:“ 程序出错了 ”,那可能将会遗漏非常重要的信息。
如果你看到了错误的信息,请仔细、精确的告诉了程序员,这很重要!在这种情况下,程序员只需要修正错误,而不用去找错误。他们需要知道哪里出错了,而电脑显示的错误信息正好能够帮助他们。如果你没有更简单的方式去记住这些错误的话,请把这些错误写下来。只报告「程序出现了一个错误」是没有意义的,你应该同时将错误信息也一块报告上来。
特别是,当错误信息含有数字时,一定要把这些数字告诉程序员。可能你并不看出这些数字代表什么意思,但不意味着它没有任何意义。数字里面包含了很多程序员可以读取的各种信息,而且可能包括重要的线索。用数字来代表错误信息是因为计算机很难用语言来描述它发生的问题,用这种方式告诉你错误的所在是最好的办法。
在这种情况下,程序员能够高效地完成排错工作。他们不知道发生了什么,也不能近距离的观察发生的事情,所以他们会尽可能地寻找有用的线索。错误的信息、令人费解的数字串,甚至是无法解释的延迟都相当重要,请保留它们。
如果你们使用 Unix 系统,程序可能会产生一个内核输出。内核输出是线索的重要来源,所以请不要丢掉他们。另一方面,大部分的程序员都不喜欢通过邮件来接收大的内核文件,所以在发邮件给他们之前,最好先问一下。还有一点要注意一下,内核输出文件记录了完整的程序运行状态:也就是说任何「秘密」(可能程序正在处理私人信息,或者在处理秘密数据)都可能包含在内核文件中。
五、出了问题后,我做了...
当错误或者 bug 出现的时候,你可能会做这些事情。但大多数会让问题变得更加严重。我有一个朋友在学校误删了她所有的 Word 文档,在寻求专业人员的帮助之前,她试图重装 Word,然后她试着运行 Defrag. 这些操作对于恢复她的文件毫无作用,而且还会打乱磁盘的文件区块,所以世界上没有任何反删除的软件可以恢复她的文件,如果她不那样做的话,还有一丝希望。
用户这样的行为就像是一只被逼到墙角的鼬,背靠墙壁,面对死亡的来临,疯狂的攻击,因为他们觉得做点什么总比什么都不做要强,但这并不适合计算机产生的问题。
不要做一只鼬,而要像羚羊一样。当羚羊面对它们没有想到的情况或者受到惊吓的时候,它们会一动不动,保持绝对静止,尽量不吸引任何注意力,然后停下来思考和制定最好的应对措施。当它们找到了最安全的方案,便会去做。
当程序出问题的时候,请停止做任何事情。不要去按任何按钮,仔细看屏幕,然后观察那些不正常的事情,记住并记录好。当它看起来比较安全的时候,或许可以开始小心地点击「OK」或者「Cancel」。试着养成一种习惯:「当一台电脑出了问题,先不要进行任何操作」 。
如果你想解决这个问题,关掉出了问题的程序或者重启电脑都不是一个好的方法,最好的解决方法是重现这个问题。程序员们喜欢可以被重现的问题,快乐的程序源码能够更快更有效率地修复 bug.
六、描述症状很重要
并不是只有非程序员才会写出很糟糕的 bug 报告。我也看过很多很差的 bug 报告出自程序员之手,有些甚至出自很优秀的程序员。
我曾经跟另一个程序员一起工作,他一直在找代码中的 bug,经常找到一些他自己解决不了的 bug,然后让我帮忙解决。“ 出什么问题了? ” 我问。然而他的回答却总是一些关于他对这些 bug 的意见。
如果他的意见是正确的话,那确实是一件好事。意味着他已经完成了一半的工作量,并且我们可以一起完成另一半的工作,这是非常有效率并且是有用的。
但是很多时候,他的观点都是错的。我们需要花很多的时间去寻找产生错误的地方,但是最后我们经常会花了半个钟在原本正确的代码中寻找错误,而实际上问题出在其他地方。我敢确定他肯定不敢对医生这么做。“ 医生,我得了一种怪病,给我开个方子吧 ”。 人们知道不应该对医生说这些。我们应该描述哪里不舒服、哪里疼,然后让医生来判断问题的所在,以及应该怎样进行治疗,否则医生将会把你当成「神经病」。
程序员也是这样,提供自己的判断可能会有所帮助,但最好还是把「症状」说出来。判断是可有可无的,但是「症状」一定要说出来。同样,在 bug 报告中附上一份修改后的源代码是一个很好的补充,但并不是描述「症状」的替代品。
如果一个程序员让你提供更多的信息,请不要应付。以前有一个人向我报告了一个 bug,然后我让他去敲一个命令,我知道这个命令不好用,但我想看看程序会返回一个什么错误(这是很重要的线索),但他并没有试。他只是发邮件跟我说:“ 那并没有作用 ”。然后我花了很多的时间去说服他试一次那个命令。
使用你的聪明才智来帮助程序员是一件很美好的事情。即使你的推论是错误的,程序员也应该感激你,至少你想去帮助他们,让他们的生活变得更加轻松。不过,也不要忘了报告「症状」,否则只会让事情变得更加糟糕。
七、真是奇怪,刚才还有问题,现在就好了
「间接性错误」确实很让程序员发愁。进行一系列简单的操作,然后就能产生错误的问题是很容易解决的。程序员可以在一个便于观察的情况下重复那些操作,然后观察它们究竟发生了什么。但是很多问题在这种情况下是不能解决的。例如:每星期出一次错,偶尔出一次错,或者在程序员面前从没有出错过,但经常会在截止日期快到的时候出现。
大多数的「间歇性故障」并不是真正的「间歇」。他们中大多数跟某些地方是有联系的。有一些错误是机器内存溢出造成的,有一些因为另一个程序在不恰当的场合修改重要文件造成的,还有一些发生在每个小时的前半个小时(我确实遇到过这些问题)。
另外,如果你可以重现错误,但程序员却不行,那么你的电脑和他们的电脑可能在某些地方是不一样的,而这个区别就是造成这个问题的原因。我曾经写过一个程序,它的窗口会缩成一个小球悬浮在屏幕的左上角,它在别的机器上只能在分辨率为 800 × 600 时工作,但是在我的计算机上却能在 1024 × 768 的分辨率下工作。
程序员很想知道与你发现的问题相关的所有事情。如果可以的话,请在另外一台机器上试一次、两次甚至三次,观察它是不是经常出错。如果问题出现在你做了一系列严谨的工作之后,而且并不是你想演示就能够演示出来的话,那很可能是长时间的运行或者是处理大文件导致出错的。程序出错的时候,请尽可能记住你之前做了什么操作,如果你看到了什么图形,也记得提醒一下。你提供的信息都是有帮助的。即使它只是「概率性」的出现(比如当 Emacs 运行时他往往会更频繁地崩溃),这可能不会提供问题原因的直接线索,但有助于程序员重现它。
最重要的是,程序员将要确定他们是否在处理真正的间歇性故障或者是机器特定的故障。他们会想知道很多关于你电脑的细节,由此来弄清楚你的电脑和他们电脑之间的区别。很多这些细节都取决于特定的程序,但是有一件事你应该准备好,那就是「版本号」,程序本身的版本号、操作系统的版本号以及可能会跟问题有关的其他程序的版本号。
八、我把磁盘装进了 Windows...
在 bug 报告中,将问题描述清楚是必要的。如果程序员不能理解你说的是什么意思,那你跟没说是一样的。
我收到的 bug 报告来自世界各地。有很多是来自非英语国家的。他们通常会因为他们自己英文不好表示歉意。但总的来说,他们的 bug 报告还是非常清晰而且有用的。几乎所有最不清楚的报告都来自母语为英语的人,他们以为只要随便说说,就能让程序员明白他们的问题。
请明确点:如果你能够使用两种不同的方式,请说明你使用了哪一种。例如,我选择加载可能意味着「我点击加载」或「我按了 Alt + L」,说清楚你究竟做了什么,是很重要的。
请详细点:信息越多越好,如果你说了很多,程序员可以忽略掉其中的一些东西,但是如果你说的太少的话,程序员就得回过头来问你更多的问题。我曾经收到过一个「只有一句话的 bug 报告」。每次问他更多事情时,他只是简单地回复一句话。然后整整花了我好几个星期才获取到足够的信息。
慎用代词:不要使用像「it」或者「the window」之类的词语,当它们指代不明的时候不要用。举个例子,“ 我开启了 FooApp,它弹出了一个警告窗口,我试着关闭它,然后他就崩溃了 ”。用户究竟试着关闭什么,这并不清楚。他们是试着关闭警告窗口,还是整个 FooApp?你可以这样说 “ 我开启了 FooApp,它弹出一个警告窗口,我试图关闭警告窗口,然后 FooApp 就崩溃了。” 这虽然比较长而且比较啰嗦,但是却比较清晰而且不容易产生误会。
仔细检查:请仔细阅读你自己写的 bug 报告,你觉得它是否清晰?如果你列出了一系列可能会导致失败的操作,请尝试自行跟踪,看看你是否遗漏了哪个步骤。
总结
bug 报告最重要的就是让程序员亲眼看到错误,如果你不能在他们面前让程序出错,那就给他们具体的细节说明,让他们能重现错误。
如果最重要的目标没有成功,程序员没法亲眼看到错误,那么 bug 报告的第二个目标就是去描述出现了什么问题。描述所有的细节,说出你看到的所有信息,并说出你期望看到的。请记录下错误信息,特别是「错误数字」。
如果你的电脑出现什么意想不到的事情,不要动。在你冷静之前,请不要作出任何你认为可能会很危险的事情。
如果你认为可以的话,请尽量自己先诊断错误,如果你这样做的话,你还应该将「症状」报告给程序员。
如果程序员需要的话,请提供额外的信息,如果他们不需要的话,他们是不会要求的,他们不会故意为难自己。如果你手中有版本号的话,很可能是必要的。
请表达清楚问题所在,并确保他们不会被误解。
总的来说,请尽可能「精确」,因为程序员喜欢精确。
推荐好文