# @ C2 B3 N* |
你听说过SEMA么? 它是一个用来测试一个软件团队有多好的相当深奥的系统。不,等等!不要手贱点开这个链接!它会花费你大概六年的时间来了解这个东西。所以我提出了我自己 的、跟它相比极不负责任的、草率的评价一个软件团队的质量的测试。这个测试最棒的方面是它只会花费你3分钟的时间。你节省下来的所有时间,还可以去上个医学院。; M' B. g0 `$ K
Joel 测试(The Joel Test Do you use source control? Can you make a build in one step? Do you make daily builds? Do you have a bug database? Do you fix bugs before writing new code? Do you have an up-to-date schedule? Do you have a spec? Do programmers have quiet working conditions? Do you use the best tools money can buy? Do you have testers? Do new candidates write code during their interview? Do you do hallway usability testing?
; [1 p8 T# J3 q' ], A. J
Joel测试的好处是很容易快速得出针对每一个问题的“是”或“不是”。你不必去翻出那些每日编程行数和每个拐点的平均bug数。如果你的团队有一个“是”就得一分。关于Joel测试令人失望的是,你真的不应该用它来确保你的核电站软件的安全。 获得12分是完美的,11分也还可以容忍,但10分或更低的分数表明你有严重的问题。事实上,大多数软件企业都以2分或3分的分数在运转着,他们真的很需要帮助,因为像微软这样的公司一直以来都以12分的完美表现在运转。 当 然,这些都不是决定成败的唯一因素:特别是当你有一个正在开发没人要的产品的伟大的软件团队的时候,那么,人们是真的不会接受这个产品的。同时一个没有这 么做的“神枪手”仍然能产生出令人难以置信的改变世界的软件也是可能存在的。但是,在其他条件相同的情况下,如果你把这12件事情都做好了,你就会拥有一 个能始终如一完成任务的团队。 你使用源代码管理么? 我用过商业源代码管理包,也用过CVS,它是免费的,让我来告诉你,CVS很好用。但如果你没有对源代码进行管理,你就要应激尝试把程序员都弄到一块来工 作。程序员根本不会知道别人都做了什么。犯过的错误不能轻易改过来。关于源代码管理系统的另一个好处就是源代码本身可以在每个程序员的硬盘上进行验证 —我还从没听说过哪个使用源代码管理的项目丢失了很多代码。 你能在一步之内编译程序么? 通 过这条测试我想明白:从最新的源代码的快速复制到进行能输出的编译需要多少步骤?再优秀的团队里,有一个单独的脚本,它能从零开始对代码做一个全面的检 查,重新编译每一行代码,生成EXE文件,在他们各种各样的版本、编程语言和#ifdef宏定义组合,创建安装包和最终媒体–CDROM布局、下载网站 等等。 如果这个过程需要一个以上的步骤,就很容易出现误差。当你接近完工的时候,你很想有很快的修复“最后一个”bug的周期,生成最后的EXE文件等。如果编译代码要用20步才能完成,运行安装编译器,……,等等,你会抓狂的,并且会导致你犯下愚蠢的错误。 正式由于这个原因,我曾工作过的上个公司就从“聪敏”模式切换到了“软件安装打包”模式:我们要求安装过程中可以运行,使用NT调度从脚本整晚自动地运行,“聪明”模式做不到这些,所以我们就抛弃了这个模式。 你每天都编译代码么? 当 你使用源代码管理的时候,有时候程序员偶然会检查出会停止编译的东西。比如,他们添加了一个源文件,一切在他们的机器上编译起来都很好,但他们忘记把源文 件添加到代码库里了。所以他们锁定了机器就回家去了,比较健忘也比较高兴。但其他人都不能继续工作了,所以他们也不得不很不愉快地卷铺盖回家了。 打 断编译是很糟糕的(也很常见的),但它能帮助程序员每天都编译代码,以确保不会出现没有预兆的编译中断。在大型团队里面,一个很好的确保中断能迅速修复的 方法是每天下午都对代码进行编译,比如可以在午饭时间做这个。每个人都尽可能多地在午饭前做代码检查。这样当他们吃完午饭回来的时候,这个编译就已经完成 了。如果它能用,就太好了!每个人都对最新的源代码进行检查,然后才继续工作。如果编译失败了,你就修复它,但每个人还能在预编译、没有中断版本的源代码 上继续工作。 在Excel项目组,我们有一条规则:谁中断了编译,作为对他的“惩罚”,他就要在其他人中断编译之前临时照顾代码编译的工作。这是一个很好的不中断编译的激励方式,也是一个让每个人轮流参与编译工作从而都能知道编译原理的好方法。 你有bug数据库么? 我 不在乎你怎么说。如果你在开发代码,即使是在一个人的团队,没有一个组织的列出代码里所有已知bug的数据库,你将会产生出低质量代码。许多程序员都认为 他们能把众多的bud存在脑子里。真是胡说八道。我根本就不能再同一时间记住两个或三个bug,第二天早上,或者在写代码的高峰时期,就记不起它们了。你 绝对要正式地跟踪bug。 但数据库可以是复杂或简单的。一个最小限度的bug数据库必须包含以下对每个bug的数据: 再次出现这个bug的完整步骤 预期的行为 观察到的行为 它是被设计来干嘛的 它是否已被修复
9 }3 s& ?) s% _, \# H# N* |
如果bug跟踪软件的复杂性是让你不想跟踪你的bug的唯一理由,只用上面包含简单的5个元素的表格用在这些至关重要的领域,开始使用它吧。 你在写新代码前会修复bug么? 第 一个版本的Windows系统上的微软Word被认为是一个“死亡行军”项目。不知道这项目要什么时候才能完成,它不断的延期。整个项目组在荒谬的时间里 工作着,项目再次、再次、再次延期,这时候的压力的令人难以置信的。当讨厌的事情最终出货,几年以后,微软把这整个团队都送到坎昆去度假了,他们可以静下 来做些严重的自我反省了。 他 们意识到,项目经理一直在坚持按照“日程安排”部署工作,而程序员们只是头脑简单的赶紧完成敲代码的过程,又因为修复bug阶段并没有成为正式日程安排的 一部分,这导致他们写出了及其恶劣的代码。没有能试图保持住bug不发作的倒计时。恰恰相反,据说一个程序员写了计算文本行高的代码,仅仅写了 “renturn 12;”然后就开始等待关于他的功能总是正确的bug报道。日程安排仅仅是即将变为bug的功能的检查清单。事后,这个被称为“无穷大缺陷的方法”。 为 了解决这个问题,微软普遍地采取了一种叫做“零缺陷方法”的东西。公司的许多程序员都咯咯地笑,因为它听起来是一种好像通过行政法令就能够减少bug数量 的管理思想。其实,“零缺陷”意味着在任意给定的时间内,优先级最高的是消除bug,然后才是编写新代码。让我来讲讲为什么。 一般情况下,你等待修复bug的时间越长,这个bug就需要付出的代价就越大(在实践和金钱上)。 比如,当你犯了一个编译器能捕捉的拼写或语法错误时,修复它的代价微不足道。当你第一时间看到你尝试运行的代码里有bug的时候,你能够很快的把它解决掉,因为所以的代码在你脑子里印象还很清楚。 如果你在几天前的代码里发现了bug,你会花费一段时间来找到它,但当你重读先前写下的代码后,你就会记起一切然后就能在一个合理的时间内修复这个bug。 但 如果你在几个月前的代码里发现了bug,你很可能把关于这段代码的大部分东西都忘了,要修复它就很难了。这个时候你可能正在修复别人代码里的bug,他们 可能会在阿鲁巴岛度假,这种情况下,修复bug就像科学一样:你不得不放缓步调、有条不紊、细致地开始工作,并且你还不能确定需要多长时间才能找到问题的 治疗方法。 如果你在已经售出的代码中发现了bug,你会招致令人难以置信的代价修复它。 这 是要立刻修复bug的一个原因:因为这样花费更少的时间。这关系到写新代码之前而不是修复bug之前还要等多长时间。比如,如果我要你预测写一个给列表排 序的代买要多长时间,你可以给我一个很好的估计值。但如果我要你预测修复一个安装Explorer 5.5版本后代码就不能工作的bug需要多长时间,你猜都猜不出来,因为根本不知道到底什么导致了这个bug。它可能需要3天时间才能跟踪到,或者仅仅3 分钟就足够了。 这句话的意思是,如果你有一个很多bug有待修复的日程安排,这个日程是不靠谱的。但如果你修复了所有已知的bug,并且所有剩下的都是新代码,这样你的日程安排才会更加惊人的精确。 关于把bug控制到零还有另一件重要的事,那就是你可以对竞争响应更快。一些程序员认为这点能让产品在任何时候为发售准备好。如果你的竞争对手从你的客户那里引入了一个杀手级的新功能,你就能在发售之前只实现这个功能,而不必去修复大量累计下来的bug。 你有最新的日程安排么? 这条测试把我们带到了日程安排上来。如果你的代码对生意是很重要的,会有很多知道代码完成日期怎么对生意很重要的原因。程序员在制定日程安排上是出了名的倔。“该完成的时候就完成了!”他们会这样对商务人士尖叫。 不幸的是,这并没有让一切变得更好。在发售代码之前,公司需要做太多的计划好的决定:软件演示,展会,广告等。而要做到这一点的唯一方法就是拥有一个日程安排,并保证其为最新版本。 关于要有一个日程安排的另一个至关重要的原因是,它能强迫你决定要做哪些功能,然后迫使你挑选出最无关紧要的功能并砍掉它们,而不是陷入长期的犹豫中去。 同时,跟随日程安排做事并不一定要很苛刻。
7 B% a, q: o6 A2 w8 g# j- D' ?. O0 `6 }& a) C; u
|