无痛错误追踪

作者:周思博(Joel Spolsky)
译:Paul May 梅普华
编辑:Jeff Wang 王家麒
November 8, 2000 A part of Joel on Software, http://www.joelonsoftware.com

TRS-80 Level-I BASIC只能储存两个字串变数:A$和B$。同样的我脑袋里天生就只够放两只程式臭虫(bug)。不管何时我只能记住两只。如果你要我记住第三只,先前的某一只,就会自然而然的会被遗忘在荒烟漫草的回忆中…

拥有(并使用)记录问题的资料库是[优秀软体团队](/wiki/The_Joel_on_Software_Translation_Project:%E7%B4%84%E8%80%B3%E6%B8%AC%E8%A9%A6 “The Joel on Software Translation Project:约耳测试”)的标记之一。令我惊讶的是:事实上只有极少数团队有实际进行。程式人员似乎全都自认为能用脑袋或便利贴记住所有错误,这件事实在错得离谱。

如果你能专心听一下,我想要延续我前几篇文章[无痛时程表](/wiki/The_Joel_on_Software_Translation_Project:%E7%84%A1%E7%97%9B%E8%BB%9F%E9%AB %94%E6%99%82%E7%A8%8B “The Joel on Software Translation Project:无痛软体时程”)和[无痛规格](/wiki/The_Joel_on_Software_Translation_Project:%E7%84%A1%E7%97%9B%E5%8A%9F%E8%83%BD%E8%A6%8F% E6%A0%BC(%E4%B8%80) “The Joel on Software Translation Project:无痛功能规格(一)")的精神,说明一种能无痛地进行错误追踪的方法。

首先你需要一个真正的资料库。如果是两人一组在周末程式课上写些小程式,拿文字档当资料库大概还可以。不过只要规模再大一点,就要用真正的错误追踪资料库。市面上有无数的错误追踪资料库随你选买。(厚脸皮自我推销一下:我们在Fog Creek Software也写了一套,名为FogBUGZ。要我来形容的话,这是个功能强大而且使用简单的网页型产品。)

为了示范,让我们跟着臭虫走走,看着它从出生一直到某人让它解脱为止的过程。我们将要跟着大名鼎鼎的1203号臭虫。下面是错误资料库对这只虫的叙述:

编号 1203
专案名称 Bee Flogger 2.0
范围 FTP用户端
标题 上传档案会导致FTP伺服器倾印核心(dump core)
指派给 已关闭
状态 已关闭(已解决- 已修正)
优先度 2 - 必须修正
修正于 2.0 Alpha
版本 Build 2019
电脑Computer Jill的iMac,Mac OS 9.0,128M RAM,1024x768 millions of colors
说明 **11/1/2000由_超级测试员Jill_ 发现**
  • 启动Bee Flogger
  • 建立一个未命名档案,内容只有一个"a"字
  • 点工具列上的FTP钮
  • 尝试用ftp传至你的伺服器

错误:观察;ftp伺服器停止回应。输入ps -augx显示ftp伺服器甚至停止执行,而且根目录有核心倾印。

预期:不应当掉

**11/1/2000由_超级测试员Jill_ 指派给指派给开发主管Willie**

11/2/2000 (昨天)已解决- 开发主管Willie 不予修正

不是我们的程式,Jill,那只是Linux所附的proftpd。

**11/2/2000 (昨天)已由_超级测试员Jill_ 重新启动(指派给开发主管Willie)**

这不对劲。我用一般ftp用户端连线都不会让proftpd当掉。可是用我们的程式每次都会当。Ftp伺服器不会自己「当」掉。

**11/3/2000 (今天)已由_开发主管Willie_ 指派给程式人员Mikey**

Mikey,你能不能看一下这个问题?也许你的用户端程式码某个地方有错。

**11/3/2000 (Today)已解决- 已由_程式人员Mikey_ 修正**

我想我把用户名称错传成密码或其他东西了…

**11/3/2000 (今天)已由_超级测试员Jill_ 重新启动(指派给程式人贝Mikey)**

Build 2021还是有这个问题。

**11/3/2000 (今天)已由_程式人员Mikey_ 编辑**

呃。这蛮奇怪的。让我来抓这个错。

**11/3/2000 (今天)已由_程式人员Mikey_ 编辑**

我想应该是MikeyStrCpy()的问题…

**11/3/2000 (今天)已解决- 已由_程式人员Mikey_ 修正**

啊!
修好了!

11/3/2000 (今天)已由超级测试员Jill关闭

看起来build 2022已经修正了这个问题,所以我把这个问题关闭了。

以下是事情发生的经过。

程式员Mikey正为他的麦金塔软体写新的FTP用户功能。写到一半时由于觉得不爽,就写了_自己的_ 字串复制函数。想借此教训教训公司里那些强迫要重复使用程式码的家伙!哇哈哈!

Mikey,当你不重新使用程式码时就会出事。而现在所出的事就是Mikey忘记把复制好的字串加零字元作结尾。不过他一直都没有注意到这个问题,因为大部份情况下,刚好都是把字串复制到已先清成零的记忆体里。

同一周稍后超级测试员Jill正在猛操那个程式,她把额头顶在键盘上滚来滚去或进行某些同等严荷的测试。(恰巧的是大多数优秀的测试员都叫做Jill或Gillian等等。)突然间发生了 非常 奇怪的事情:她测试用的ftp伺服器_当掉了_ 。不要怀疑,我知道这是台Linux机器而Linux机器是不会当的(slashdot的人拜托不要嘘我)。不过这个该死的东西就是_当了_ 。而她根本没有动过伺服器,她只不过用Mikey的Mac程式把档案FTP上去而已。

现在呢,由于Jill是个超级优秀的测试员,所以她会小心地把所做过的事记下来了(比如在实验手册上精确记录头在键盘上滚动的方位)。她找一台干净的机器从头开始重复每个步骤,看吧,又 发生了! Linux的ftp daemon 当了!这么一来一天内就发生两次了! Linus(译注:创造Linux的人)注意啦。

Jill斜眼看看重现步骤清单。总共大约有20个步骤。其中有几个似乎与问题无关。做了一点实验后,Jill已经能把问题缩减到四个步骤,而且每次都能产生相同的结果。现在她已经准备好把问题发出来了。

Jill在问题追踪资料库中输入新错误。这里光是输入错误的动作就是有学问的:有好的错误报告也有不好的错误报告。

优良错误报告必备的三元素

然后主说话了,祂说「你要先取出圣撞针。然后你要数到三,不多,不少。三是你要数的数而要数的数就是三。四不是要数的数,二也不是,除非接下来要数到三。五完成不行。当数到第三个数字三时,就把你的安提阿金手榴弹投向你的敌人,那些在我眼中极其下流的人,他们必须承受」 -- 圣杯传奇

写一份优良错误报告的规则很好记。每个好的错误报告都要有刚好三个东西。

1. 重现的步骤,
2. 期望看到的,以及
3. 实际所看到的。

看起来很简单,对不对?可能没那么容易,身为程式员,别人丢给我的问题总会缺一两点。

如果你没告诉我要怎样重现问题,我可能根本不知道你讲的是什么。「程式当了而且在桌面留下一个臭臭的大便状物体。」讲得很好,宝贝。不过除非你告诉我 你做了些什么 ,否则我是什么事都不会做的。现在我得承认有两种情况是很难找出重现步骤的。有时候是根本不记得或只是在转述「田野」中(field,译注:指实验室以外的环境)的错误。(顺便提一下,为什么他们要称之为「田野」呢?是不是像黑麦田或其他作物呢?不管了…)还有另一个可以不提供重现步骤的场合,就是问题 时有时无 并非_一直出现_ ,不过你还是应该提供重现步骤,再加个小附注标明问题不是时常出现。在这些场合下要找到问题实在是很难,不过我们还是可以试试。

如果你不指明_你期望看到的_ ,我可能不明白它为什么是个问题。开机画面上有血迹。那又怎样?我写这段程式时割到手指啦。你希望看到什么?啊,你说规格上说 _没有血迹_ !现在我搞懂你为什么说它是个问题了。

第三部份。你实际上看到什么。如果你不告诉我这一点,我不会知道问题是什么。这是理所当然的。

回到我们的故事

Anyhoo。Jill把错误输进走了。在良好的错误追踪系统中,错误会自动分派给该专案的开发主管。这里隐藏了第二个概念:每个错误随时都要有_一个人_ 负责,一直到错误关闭为止。错误就像是个烫手山芋:当拿到烫手山芋时,你就得负责把它解决掉,或是把它丢给_别人_ 。

程式主管Willie看看这个错误,认为这个可能与ftp伺服器有关,所以就以「不予修正」把它处理掉。毕竟他们并没有_写_ 那个ftp伺服器。

问题被处理掉之后就会分派回开启的人身上。这可是个重点。不是程式人员认为没事就真的_没事_ 了。铁律是只有开启错误的人才能关闭错误。程式人员可以_解决_ 问题,意思是「嗨,我觉得弄好了」,不过要实际_关闭_ 错误并把它从清单中拿掉,最初开启的人必须确认问题真的已被修好,或是同意该问题基于某于原因不必修正。

Jill收到一封电子邮件通知她问题回来了。她看看信里开发主管Willie的说明。有些东西不太对劲。这套ftp伺服器大家用好几年了都没有当。只有用Mikey的程式才会当。所以Jill 重新启动 该问题并说明她的想法,所以问题又回到Willie身上。这次Willie把问题指派给Mikey修正。

Mikey看看这个错误,认真的想了很久,结果完全误诊了这个问题。他修正了其他完全不相干的错,然后就说把Jill开启的问题解决掉了。

问题回到Jill身上,这次标示为「已解决- 已修正」。Jill拿最新版软体试了她的重现步骤,看着看着Linux伺服器就当了。她_又_ 重新开启问题并且直接指派回给Mikey。

Mikey被难到了,不过最后还是找到了错误的根源。(知道是什么了吗?我要把它当作给读者的作业。线索可是给足了!)他把问题修好后测一测,然后 –找到了!照重现步骤去做不会再让ftp伺服器当掉了。他再一次标示「已修正」把问题解决掉。Jill也试了重现步骤,发现问题的确修好了,所以就把它关掉。

错误追踪的十大建议

1. 好的测试员一定会试着把重现步骤减到_最少步_ ;这对必须追出问题的程式人员来说极为有用。
2. 要记住只有一开始开启的人才能_关闭_ 该错误。其他人可以_解决_ 问题,不过只有最初看到错误的人可以真正确认所看到的错误已被修正。
3. 要解决错误有很多种方法。FogBUGZ中可用的解决方法有_fixed(已修正)_ , _won't fix(不予修正)_ , _postponed(暂缓)_ , _not repro(无法重现)_ , _duplicate(重复的问题)_ ,or _by design(设计限制)_ 。
4. _Not Repro_ 表示没有人能重现该错误。程式人员在错误报告漏写重现步骤时常常会用这一项。
5. 你需要小心追踪程式版本。每次发给测试员的软体都应该有个编译ID编号,这样可怜的测试员才不必在根本尚未修正的版本上测试同一个问题。
6. 如果你是个程式员,而且想尽办法都无法让测试员使用问题资料库,只要_不接受用其他方法写的错误报告_ 就可以了。如果测试员习惯用电子邮件送错误报告给你,你就把信退回去并加上以下简短讯息:「请把它放进问题资料库中。我没法子追踪电子邮件。」
7. 如果你是个测试员,而且想尽办法都无法让程式人员使用问题资料库,只要_停止向他们报告错误_ 就好了- 把错误直接放在资料库里并让资料库发信通知。
8. 如果你是个程式员,而且只有部份同事在用问题资料库,只要开始在资料库里把错误分派给他们。最后他们自然会明白的。
9. 如果你是个经理,而且似乎没人在用你花大笔费用安装的问题资料库,那就开始利用它把新功能分派给大家。因为问题资料库也是个很好的「未完成功能」资料库。
10. 要避开在问题资料库里增加新栏位的诱惑。每个月总会有人想出个要在资料库里新增栏位的好点子。什么聪明的点子都有,比如追踪发现问题的档案;追踪有多少比例的问题是可重现的;追踪某错误发生的次数;追踪某问题发生时机器上某个DLL的版本。_不要_ 屈服在这些点子之下,这一点非常重要。如果你屈服了,输入新错误的画面最后会出现上千个栏位要输入,结果是没有人会想输入错误报告。要让问题资料库有效运作,一定得让大家都用,如果「正式」输入错误太麻烦,大家就会_绕过_ 错误资料库。

只要你在写程式(只有一个人写也一样),如果没有一套良好的资料库列出程式中所有的问题,一定会产生品质低劣的程式码。良好的软体团队不只会广泛使用问题资料库,其中成员还会习惯用问题资料库产生待办事项列表,并把浏览器首页设成会列出所分派到的工作,还会开始祈祷他们能把问题指派给办公室经理,叫他进多点山露汽水(Mountain Dew,译注:百事可乐的著名饮料)。


Fog Creek Software制作了一套易用的问题追踪软体,名为FogBUGZ

这些网页的内容为表达个人意见。
All contents Copyright 1999-2002 by Joel Spolsky。All Rights Reserved。