开发团队到底好不好,这 12 个问题能检验出来吗?
【伯乐在线导读】:「Joel 测试」是 Joel Spolsky 在 2000 年提出的 12 个问题,用来检验一个团队是否是好的开发团队。17 年过去了,Dale Myers 重新审视了这12个问题,并与时俱进地提出了修改建议。
就在 2013 年,我参加了一个课程:“软件的架构、执行和管理”。其中主题之一,就是如何评价一个开发团队?这不是一个简单的问题,如果要得到一个完整的答案,最后一定需要一些必要的研究,一篇冗长的报告。还好,Joel Spolsky 提出了12 个非常简单的测试问题,相对无痛地解决这个问题,这些问题被称为“Joel 测试”。该测试不是非常严谨,也无意于此。但是它可以为你提供坚实基础,进一步了解其他细节。
1. 是否使用源码控制? 2. 能实现一键编译吗? 3. 是否进行每日编译? 4. 有无 bug 数据库? 5. 在编码前是否解决bug? 6. 是否有实时更新的计划表? 7. 是否有文档? 8. 开发人员有安静的开发环境吗? 9. 是否使用市面上最好的工具? 10. 是否有测试人员? 11. 新员工面试时写代码吗? 12. 是否进行走廊可用性测试?
Joel 测试的优点在于:仅仅通过很小一组是非题,就可以得到需要的答案。你无需关注任何例外,或任何附加条件,只需要单纯的关注每个问题的答案是 yes 还是 no,就可以得到需要的结果: 12 分为优,11 分为良, 10 分及以下为差。这个优点并没有被我和我的几个同学忽视。我立刻将这个方法用到评估那些我面试实习的公司,以及后来毕业后第一份工作的公司。大多数雇主从来没有听说过这个测试,这倒不意外。真正令人意外的是,有多少公司没有通过该测试,而我曾认为这些公司非常棒!
我提问的不准确吗?他们真的理解我的意思吗?再或者我统计 12 个问题的时候算错了?
在面试时遇到 ”你还有什么想要问我们的吗?“ 这种问题时,Joel 测试是回答这个问题的大杀器,但是基本都没有及格的。当然,有可能刚好我面试的公司都很差劲,但是,尽管我是软件行业的新人,但是我有个感觉,事实绝非如此。我将该测试带入我的一些应用,发现我竟没有在任何地方考虑到这些问题。
那么我在 Joel 测试中出了什么问题呢?
每个开发人员都是不同的,他们对好坏都有着自己的标准,而且这个标准还会随着时间变化。Joel 测试试图规避这种偏差,用客观题替代了主观题。相信没有任何开发人员会反对,跟踪 bug 是个好想法,但是其他的问题呢?
从 2000 年发布开始,Joel 测试已经有 17 个年头了。它比 OS X 的历史还要久。在同一时期,Windows 2000 还是当时技术最高水平,PlayStation 2 刚刚发布, 奔腾 III 处理器还在 1GHz 下嗡嗡地工作。 在计算机世界里,这确实是很久以前的事了。随着处理器计算能力(还有硬件的整体性能)每18个月翻番,我们的开发进程也一同提升了。Joel 测试的问题反映了当时软件开发的时代缩影。时至 2017 年,它们就未必非常恰当了。
以第一个问题为例:
是否有源码控制?
如今最流行的版本控制系统——Git,在当时还没有出现。好吧,众所周知,Git 直到 2005 年才出现。也不要忘记,前任的版本控制系统之王——Subversion 也是到 2000 年才出现,比 Joel 测试首次发布晚了 2 个月。那时源码控制出现了,但是却不像今天这样普遍。这是不是意味着,今天还讨论源码控制这个问题显得多此一举呢?可能吧!我们应该修改这个问题与时俱进吗?也许吧!
让我们一起来看看这些问题,然后看看如何与时俱进吧。
1. 是否使用源码控制?
除了上面提到的,时至今日,这个问题似乎依然有意义。任何团队都需要源码控制,这是毋庸置疑的。如今的争议主要在是否使用集中式版本控制系统。一般的项目使用 Git 或者 Mercurial (举例来说)都可以。大型公司拥有超大型代码仓库,一般采用集中式版本控制系统。这个问题没有绝对答案。真正重要的是,有版本控制!既然这个问题已经是常识,我认为它就没必要继续存在了。
更新建议: 删除
2. 能实现一键编译吗?
Joel 的解释如下:
从最新的代码快照编译出交付版本,一共需要多少步?
其背后的原因,今天依然成立。好了,我认为这是我们对老问题的第一个挑战。我一直认为,编译交付版本,应当 0 步骤完成。持续集成已经广泛存在。使用它是非常明智的。创建一个交付版本的步骤应当这样:程序员们提交代码,当管理人员,或者其他负责人准备 release 时,他只需要点击 ”release“ 按钮即可,然后就成功了。所有开发人员只需要确保他们提交的代码无误,持续集成服务自动会完成其他工作。
持续集成系统将软件开发产业向前推进了一大步。如果我们能更广泛的使用,充分发挥它的潜力,我们将受益良多。
更新建议:所有版本,都由持续集成服务器自动编译吗?
3. 是否进行每日编译?
这个问题紧随第 2 个。如果对团队有用的话,每日编译是可行的。我一直认为每日应当是最低限度了。在我眼里更好的实践是,确保主开发分支的每一次提交,都可以正常的完成编译。这算是一种“预览”版本,同时也意味着你能更快、更有效地发现自己的问题,因为一旦发生任何故障,非常容易确认其版本。
该编译过程应当由持续集成系统自动完成。还有,你不止应当进行每日编译,而且应该使用它们。当然,如果你开发那些与你日常工作无关的软件时(定制或者专业软件),很难做到这一点。比如你在开发一款会计软件,或者火箭控制程序,显然你不可能使用这些产品。然而,我的建议是,每天至少花20分钟看看你的软件,试用一下,确保一切正常。假如你开发的软件每天都能用得到,那就更好了。它的作用与前面提到的 20 分钟试用一样,但在实际操作中,你可以进行远超 20 分钟的测试,使项目暴露在更加真实的场景下。
更新建议:是否执行每日编译,并使用这些版本?
4. 有无 bug 数据库?
当然啦,你应该使用某种 bug 数据库。你听说过任何人认为没这个必要吗?如今发生变化的是,bug 跟踪有了更加丰富的特性。它们已经不再单单是一个数据库表的接口,而是拥有丰富功能的规划、管理程序,通常在任务和 bug 之间有显著区别(参考第 5 条)。
如今,当你提交一个bug时,它有标题、描述、复现步骤、影响平台等等信息,一般都是如此。如今不同的是,管理将贯穿你的 bug 处理,bug 会被分派到若干迭代中,你需要利用看板规划任务,你的敏捷开发组长会就那些有困难的任务与你进行谈话。
问题跟踪器也不仅仅是记录需要做的事。它包含谁执行了操作,对团队的影响,对产品的影响,以及其他上百个属性。那么,我认为你应该有某种软件来做这些事情,这都不重要,它就是你的某种问题跟踪器。因为各个团队的情况有所差异,这个问题也没有确切的答案。我所做的一点调整,只是为了用文字的一点不同,来反映我们现有的能力。
更新建议:你是否使用问题追踪器(issue tracker)?
5. 在编码前是否解决bug?
Joel 对这一点的重要性给出了非常好的论述,17 年后的今天,它依然成立。
更新建议:无
6. 是否有实时更新的计划表?
作为开发人员,你可能没那么关心计划表。如果你的团队没有在按时完成任务会怎样?不是你的问题吗?把这个问题留给管理人员吧!
留个管理人员,也许有用,也许没用。如今,我们有各种敏捷开发理论,从开发人员,或者其他任何估时比较靠谱的人那里,得到的项目预估,是进行项目规划的关键要素。这帮助我们安排团队工作、谁来做这些工作,以及何时做这些工作。你可以掩耳盗铃,假装事事与你无关,但是最终,每一个人都需要对整个团队有一份责任。
这一条今天还有效吗?必须的!当然了,我们已经不用瀑布流了。确保准时达到测试阶段,对我们已经没有太多意义了,但在敏捷开发(很多人深信,跟“现编现造”一个意思),特别是敏捷开发,计划表是最重要的,而且需要时刻保持更新。如今不同的是,计划表会根据新信息,保持更新。
更新建议:无
7. 是否有文档?
计划表那一条完整的被保留下来,文档却未必同样走运。在瀑布流流行的时候,文档是你了解开发目标的关键。如果你无法有效调配资源,那么你的项目,注定会失败。
回到 2001 年,当你创建一个程序时,无论是一台咖啡机,一台火箭,或者只是一个简单的 CRUD(Create、Retrieve、Update、Delete等) 界面,你都很清楚需要做什么,以及大约需要多少开销,逐步实现它。开发人员、测试人员、项目管理人员各司其职,大家全程根据文档展开工作,测试,交付,然后进入下一个项目。而今,在很多方面已经不是这样了。当然了,如果你还在开发上面提到的东西,情况就基本没什么变化。但是,如果你在开发 Twitter 客户端呢?或者文本编辑器呢?再或者邮件客户端?以前的老方法还依然有效吗?通常不是。
只有当你可以从一开始就获得所有信息,并用来完成规划,文档才是有效的。当你的软件需要持续开发时,文档只在 MVP(Minimum Viable Product,最小可行产品)阶段比较重要,在此之后,它的用处就很小了。要让文档在今天依然保持重要性,就必须实时更新信息,并相应地适应当前进度和产品情况。
这里所谓的信息,可以通过很多形式获得。可能只是简单的模拟用户如何使用APP,或者应该更进一步,如果可能的话,应当对新特性和设计进行 A/B 测试。
更新建议:是否有关于产品功能和使用相关的最新信息?
8. 程序员有安静的开发环境吗?
当回想八九十年代的软件开发环境,一片小隔间的海洋就会进入脑海。如今,情形基本没变,唯独发生变化的是,隔断变得更小了,或者隔断在所谓的“开放式”办公室里,直接消失了。
我个人而言,我并不喜欢开放式办公室。我喜欢自己的办公室,我就可以拥有单独的开发时间,完全看我的喜好,我可以打开音乐,让我步入状态。然而并不是所有人都同意我的观点。我知道很多人喜欢开放式办公,这样更加有效率,促进团队成员之间直接沟通,通常可以获得更快、更好的问题解决方案。
这条规则对工作环境的要求,并不是什么特例。开放式办公室,通常比你自己的办公室更加嘈杂。每当有人问起关于开放式办公室的噪音问题时,我通常的解决方案就是带上耳机。通过消音技术,基本能解决绝大多数问题。这是我平常在开放办公室的办法。
总之,安静的工作环境,无非就是独立办公室和开放办公室之间的取舍,这两个也没有孰优孰劣。
( 《 国内程序员的办公桌是什么样的?》文中黄钊的晒图 )
更新建议:删除
9. 是否使用市面上最好的工具?
这一条是最难取舍的,事实上我是写完本文其他部分以后,才回头写这一部分。
我通常遇到的情况是这样的,公司无法负担市面最好的工具。也就是今天无法负担而已,不代表以后不行。我认为这一条规则的精神依然是成立的。公司应当有义务,尽可能保证开发人员的工作惬意、开心。愉快、宽松的程序员会生产更好的代码。
有一点一定要切记,这并不意味着必须要用重金砸向这些问题,如果优秀的工具是免费的,那肯定还是要用免费的。
(《 国外程序员的办公桌是什么样的?》,网友「土豆」晒图)
更新建议:无
10. 是否有测试人员?
不同公司在测试方面是有区别的。几年前,就在我还是个实习生,到成为全职之间那段时间,微软复用工程师作为测试人员。我曾撰文说明, 为什么我认为微软复用开发和测试人员,很好的说明我作为实习生浪费了多少资源,还消除了曾鼓励我编写更好代码的安全网。现在这都在微软得到印证,我们还是看看 Joel 对此是怎么说的:
如果你的团队没有专业的测试人员,至少每 2~3 个开发人员一个测试人员,你要么会交付缺陷产品,要么你让时薪 $100 的开发人员,去做时薪 $30 测试人员的工作。
我和 Joel 观点的主要不同是,对于微软而言,开发人员和测试人员是一样的,开发人员的薪酬并不是测试人员的 3 倍。测试人员花费时间,遍历代码变更,确保提交的修改可用,而且没有引入新的问题,这些都与开发人员的时间一样有价值。当然,这也算安全网。
拥有测试人员是很好的选择,但是 Joel 提出了更好的观点,那就是,你千万不要浪费测试人员的价值。
开发人员需要对自己的代码负责。如果你不是特别确信自己的代码无 bug,就不应当提交。这意味着你需要进行人工测试、单元测试、集成测试等等。既然在未进行代码 review 之前,代码是不可提交的,那没有进行测试,又怎么可以提交呢?
测试人员不需要遍历每一个变更,但是他们需要确保,产品作为一个整体依然是稳定的。他们应该能将他们的时间投入测试模型,这远比开发人员更加有价值。有测试人员并不是最关键的,有完整有效的测试计划才是。
更新建议:是否有完整的测试计划。
11. 新员工面试时写代码吗?
当你在很多类似 Hacker News,或者一些 Reddit 之类开发网站搜索关键字“面试”时,结果中的文章有多少对现在的面试流程是正面评价呢?非常少!每个人都很清楚,现在的面试系统很烂,我们需要更好的选择。在某人想出更好的之前,就当现在只有这么一个办法,虽然看起来不像什么好点子,我们就将就一下吧。
目前有如下一些不同的面试方法:
- 白板面试。
- 做一个家庭作业式的小项目。
- 到公司来,与我们一起工作 6 个月,作为试用期。
有件事我们都有共识,开发人员应该编码。既然这是他们的工作,那你就应该在这方面测试他们。就不要用查找特定的语法错误这种问题来为难他们,也不要让他们选择你的团队的工作语言了,只要确保他们可以编码即可。
就像我们前面看到的,这一条也是非常常识的问题,我觉得就没必要继续保留了。
更新建议:删除。
12. 是否进行走廊可用性测试?
这是一条鲜为人知的规则,我们看看 Joel 的定义:
走廊可用性测试是这样的,你在走廊里,随手请一位路人,帮忙测试你刚刚编写的代码。如果如此请了 5 个人帮忙,你就可以找到代码中 95% 影响可用性的问题。
现在,如果我说走廊可用性测试是个好东西,应该不会有太多人反对吧,但是对于灰色桌面背景上的灰色工具栏,上面还有灰色按钮的情况,这就未必了。电脑用户(如今这个定义非常宽泛)通常不是特别了解其工作原理。对于专业工具,你可能需要按钮提示信息、拖拽支持、键盘快捷方式等,这样就非常棒了。然而对于 Facebook,得让你的爷爷奶奶也能用才行。这需要清晰的设计:元素之间采用高对比度,在合理的位置进行交互,还要有适合的大小。
在各种情况下,需要创建用户界面和用户体验,我所说的不仅仅是常规的 UI,而是类似“以合理的方式,控制文件保存操作”这样的事,这已经不是一个开发人员能做到的了,应该由专业人员来做。现在这是专业的 UI 和 UX 设计师应该掌握的一种专业技能。
更新建议:是否有专业的 UI 和 UX 设计师?
现在我们看看「Joel 测试」变成什么样了:
1. 所有版本都是由一个持续集成服务自动完成的吗? 2. 是否生成并使用每日版本? 3. 是否有问题跟踪器? 4. 写代码之前修正所有 bug 吗? 5. 是否有实时更新的计划表? 6. 是否实时更新产品功能和使用方法的文档? 7. 是否使用市面上最好的工具? 8. 是否有完整的测试计划? 9. 是否有专业的 UI 和 UX 设计师?
我们砍掉了部分规则,修正了其他的。但是这还没完。这只是我们如何修改已有规则,使之与时俱进,但是我们还需要新增一些如今非常重要的规则。
新增的 3 个规则
所有代码都经过 review 了吗?
每个人都会犯错,无论你是刚刚毕业的新人,还是身经百战的编程老司机,你都会犯错。我们总是过于依赖编译器帮我们发现错误,这并不是编译器的正确使用方法。这就是我们需要“测试”的原因。但是测试也可能失效,我们不能 100% 依赖它。对你的代码擦亮眼睛,能让你发现平时未发现的东西。除此之外,这还能让你的代码与团队代码风格保持一致,编译器通常不具备这样的能力(代码检查这个主题,我们换个机会再谈)。一致性良好的代码,可以方便团队成员阅读、使用你的代码。
是否有编码标准?
这条规则与上面一条相互依存。编写代码非常重要,但是最终你需要能重读你的代码。很遗憾,现实并不是这样。所以,我们应该尽可能让代码易于阅读。首要任务就是,保证代码库的一致性。通过制定一系列规范,在团队内贯彻,令代码易于阅读和理解。在代码库中搜索最常用的模块、类型等等,清晰定义期望的代码风格,帮助新进开发人员逐步跟上进度,这比在开发过程中一点点明确风格要好的多。也可以在持续集成系统中,增加自动代码检查工具,推进这些代码规范。
新员工是否有培训?
这看起来显而易见,但事实上却并不常见。很多新进开发人员,加入一家公司,就立刻被投入深水区。这个过程对开发人员和公司,都是浪费。有一些会试着游起来,但是绝大多数会沉没。当你加入一家公司后,你应当获得工作所需的一些必要信息。我并不是说你应该在一间会议室里待一周,学习 HR 课程、聆听 VP 的宣讲,这确非我的本意。实际上你应该获得你所工作系统的文档,并且,有一位团队成员,给你当一段时间导师,以帮助你尽快跟上进度。没错,这意味着这个开发人员可能在培训阶段的输出会有所减少,但是在此之后,你就获得了两个开发人员,任何会算数的人,都会看出来,这事一笔值当的投资。
结语
那么,我们看看我们 2017 版 “Joel 测试”是怎样的:
1. 所有版本都是由一个持续集成服务器自动完成的吗? 2. 是否生成并使用每日版本? 3. 是否有问题跟踪器? 4. 写代码之前修正所有 bug 吗? 5. 是否有实时更新的计划表? 6. 是否实时更新产品功能和使用方法的文档? 7. 是否使用市面上最好的工具? 8. 是否有完整的测试计划? 9. 是否有专业的 UI 和 UX 设计师? 10. 所有代码都进行 review 吗? 11. 是否有代码规范? 12. 新员工有培训吗?
好棒耶!让我们喜大普奔地照办起来吧。
还是不要了!该测试不是万金油,只是个指导意见。它是一个指导系统,而非一套完整的评估系统。一个得到满分的企业,依然可能是一家不宜工作的地方。当然,如果一家公司连 10 分都拿不到,那这是家不靠谱的公司基本没跑。只要确保你的雇主能获得 11~12 这样的高分,然后根据自己的判断来。千万不要迷信!