这篇文章来源于一段真实的经历:
我的一位朋友曾经和我讲起他的担忧:这位朋友白手起家,现在管理的软件公司已经有三十多人。因为历史的原因,公司的开发一直比较混乱。代码管理问题,版本丢失和冲突经常出现。测试没法做得很好。给客户交付的软件质量都很让人担心。计划之类基本上也都是靠拍脑袋。他问我:怎么才能开始让公司有一套比较完善的开发流程?哪个流程比较适合他们呢?
各位读者大人,你们碰到过这样的事情吗?最终又是怎么做的呢?
在这篇文章里,我将和大家分享我们在这个具体案例上是怎么做的。这些做法很可能也适用于你身边的情况,因为很多软件企业也都经历过这样的阵痛与转型。这也是为什么我推荐大家看完这篇文章的原因。
我们在这个案例中的做法是基于以下的考虑(事实上这些观点的正确性也在后面的实践中得到了验证):
- 流程改进要切忌生搬硬套或者用力过猛,需要结合自身情况进行渐进式的改善。
- 先列出需要解决的痛点,首先思考如何通过一些工具或者流程来解决这些痛点,然后再来思考大的流程。
- 流程改进需要有优先级,很多事情同时进行,不一定能兼顾得过来。
- 在实践中总结和观察改进的效果。并不断修正。
列出需要解决的痛点
痛点有很多。我们采取的方法是首先和老板和几个经理聊了一下,了解他们眼里的问题。之后又和员工开了几次头脑风暴,最后把这些问题总结出来大体如下:
- 项目估算时,每个人说法都不一致,吵来吵去最后只好拍脑袋。
- 需求了解不清楚,有时候开发了好长时间的功能,突然在沟通中发现根本不是客户想要的。只能重做。
- 团队沟通也有问题,比如项目客户说一个事情,可能项目经理和不同的人说,最后每个人说法都不一样了,而且有时候项目经理自己都忘了是怎么回事。
- 开发缺乏设计,经常做到中间才发现需要推倒重来。
- 代码缺乏规范,可读性也差,一个人写的代码,另外一个人很难看懂。
- 因为代码的问题,有时候一个开发工程师辞职了,整个项目要受到很大影响。
- 测试不充分:因为时间不足,很多测试不够全面。而且测试组人手有限,代码修改频繁,也很难一遍又一遍做回归测试。
- 项目缺乏可追踪性和可预测性:每个人对项目做了多少,还需要多久都有自己的看法,有时候观点差异很大。
- 工作缺乏计划性,每个人都很忙,开发忙着写代码,改bug,测试忙着一遍又一遍测试,效果却不大好。
- 质量无法控制,同一个bug经常反复出现,改了一个bug又可能引起了新的bug
- 客户那里,最后发布的产品时间经常达不到逾期,而且出了很多质量问题。
这些问题,也许读者大人们会很熟悉,因为这几乎也是发生在许多软件公司的事情。而这,也是为我们说这篇文章里的实践具有借鉴意义的重要原因。
事实上除了这些,我们所记录的痛点还有很多,比如很多员工抱怨知识得不到更新升级之类,但是因为本文篇幅所限,我们仅列出了比较重要也比较有共性的一些点。
确定改进目标和优先级
问题有很多。不过就像我们之前指出的那样,人的精力是有限的。在这种情况下,总结出一些重要的改进目标并排出优先级就很必要了。
我们总结出的改进目标如下:
- 改进需求管理和客户沟通,以避免因需求导致的返工和推倒重来的现象。同时尽力细化需求以改进估算。
- 加强产品质量管理,包括测试流程再定义,推进版本管理和配置管理等。
- 改善团队协作
- 增强代码质量和设计优化
上面的排序就是优先级的排序,越往前的目标优先级越高。
有一些朋友可能会问:这种优先级的排序是否合理呢? 比如代码质量难道不重要?其实这只是基于当时这家公司的具体情况作出的考虑。需求和产品质量对于一个小公司来说几乎是致命的因素。如果不能做出客户想要的产品,或者产品质量影响了客户使用,那么这家公司随时可能受到毁灭性的打击。因此我们把他们排列在了前两位。
渐进式改进
流程改进表
确定了流程改进的目标和优先级。我们开始指定具体的改进策略和步骤。我们在具体实践中使用了一种叫做流程改进表的表格,以方便公司所有人了解我们要怎么做。
下面就是一个流程改进表的实例:
要解决的问题 | 具体如何改进 | 涉及到的人 |
---|---|---|
前期需求过于抽象,有时候客户不知道自己想要什么 | 在需求阶段就通过poc之类快速做出原型让用户有直观印象 | 项目经理,开发 |
因为表格里的内容字数较多,读者大人们用手机观看时阅读体验不大好,所以在下文我们不再展示实践中所用具体的表格,而是把表格里的内容以文字或者列表的形式展现出来。
用表格有什么好处呢?一是简明,二是便于张贴和传播,三是便于日后反馈和追踪。我也推荐您在类似的工作中试一下,效果应该会很不错的。
好了,说完了形式化的流程改进表。让我们步入正题,说一说具体进行哪些方面的流程改进。
流程改进之需求分析
每个软件团队都会进行需求分析,也几乎每个团队都在需求上吃过亏。好的需求分析工作往往能让后续的设计和开发事半功倍,而不好的需求分析则可以让一个项目刚开始就步入失败的轨道。因此我们首先做的改进就是关于需求搜集和分析的。具体的措施如下:
让开发和测试加入到需求讨论中
要求项目经理在与客户讨论需求时,至少叫上一个开发和测试一起讨论。包括拜访客户时,也尽量带一个或者两个人过去。这样做的目的包括:
- 不同的人可以提供不同的视角
- 避免出现沟通传达错误
- 可以锻炼普通工程师的沟通理解能力。
以文档的方式细化和记录需求
将需求以树形结构用简短文字记录下来,并不断细化。比如一开始可能记录了系统需要注册功能,之后就可以把注册功能分解成几个子功能:普通用户注册,管理员注册。普通用户注册又可以再分为手机注册,邮箱注册。手机注册又分为发送验证码,正确注册,注册后跳转,检验错误等等。
我们实际使用的是excel,因为excel中可以不停增加列,只要你愿意,这个功能列表几乎可以无限细化下去。
之前他们公司里面项目组成员(大多是项目经理)在与客户交谈后,记录的文档格式多种多样,有的就只有本人能看明白。而且也保存在各种不同的地方。时间久了,很多东西都找不到了。
我们建立了一个共享文件服务器,按照客户 - 项目 - 模块的层级建立多层目录。之后要求每次和客户沟通后都要维护这样的文件。包括电话或者邮件沟通,也需要更新需求文档。这也为之后的开发和测试提供了依据。
值得一提的是,具体实践中不同的企业在管理需求方面可以有不同的工具/方法。Excel是最原始的一种。您可以选择适合自己的工具或方法。
尽早做出原型并在需求中与客户讨论
原型或者叫POC是很多企业都在用的需求工具。这里要强调的是原型不必做得太完善,只要能向客户展示未来他们会大概怎么使用这个产品即可。一些细节方面不必做得太细。当然,如果客户有针对性的提出一些细节上的意见,一定要搞明白背后的需求,有时候看似细节的地方恰恰是和用户的关键使用习惯相关的。
原型的工作应该在项目需求讨论一开始就做,这对了解客户真实需求会起到很大作用。而且很多原型代码在后期仍然可以在产品开发中使用。
流程改进之需求/任务管理
使用一种协作工具管理需求(任务)
早期的需求讨论告一段落之后,正式的开发和测试就要开始了。之前团队里开发做什么测试做什么全靠感觉和口头交流。我建议他们使用一种协作工具将需求或者任务管理起来。
目前软件团队可使用的协作工具非常多。最流行和功能最全的当属JIRA/Confeluence 和微软的TFS。在本案例中最终他们选择了bugzilla,原因主要还是不想用付费的软件。工具最重要的是选择适用自己的。
虽然bugzilla主要用于管理bug,我们也把所有需求都登记在了上面。
实践中,我们在项目初期就要求测试团队把需求登记在bugzilla上,并要求项目经理把开发任务指派给对应的开发。模块开发完成并提交代码到git以后,开发把对应任务的状态修改成Resolved并指派给测试人员测试。测试完成以后就直接关掉对应的任务。而如果发现bug也是登记在bugzilla上。
具体实践中,其实这里有很多相关工作。比如这里需要持续集成的工具(类似jenkins)。后文我们还会提到相关内容。
流程改进之质量管理
在上一节中,我们提到了使用协作工具(JIRA/TFS/Bugzilla等)。其实这已经涉及到了质量管理。包括前文提到的尽早使用原型等,其实也会对质量管理产生积极效应。
持续交付并获取客户反馈
案例中的企业和很多企业类似,习惯于产品做好了才让客户进行UAT。其实尽早让客户参与进来使用比这样更好。
早期处于开发中的产品,可能功能不完备,而且bug很多。很多人担心会给客户留下负面印象。其实如果和客户做好沟通工作,并做好规划就没有问题。当然,也不能让客户代替测试团队去测试产品。不过如果完成了某些功能(指测试验收通过)能尽早让客户体验并获得客户反馈,对于产品的最终质量是会有积极作用的。
在实践中,我们会在项目一开始就和客户说明我们会希望他们在开发中阶段性的测试完成的功能并提供反馈,并要求客户指派专人负责这方面的沟通。最后也取得了比较良好的效果。客户实际很喜欢这种方式,因为他们也希望看到自己付的款能有一些看得见摸得着的进度。而在开发团队这边,则是获得了早期客户的反馈与及时的调整。
那么这种阶段性UAT以多久为宜呢?只能说没有固定答案,必须视项目情况和客户的情况而定。在本文提到的案例中,大概每两个星期左右我们就会交付一部分新功能让客户进行测试。
提高项目的自动化测试水平
自动化测试有很多层面,比如针对UI的Selenium测试,还有类似SoapUI之类的服务测试,以及JUnit单元测试。
我们这里谈提高项目的自动化测试水平,但并没有谈一定要覆盖率达到多少多少。这是基于我们前面说的渐进式改善的观点。
自动化测试的价值在于减少回归测试。所以如果你在自动化测试上花的时间少于可能的回归测试的时间(可以基于经验和历史估算),那么这种自动化测试就是合理的。否则你可以继续手动测试。当然,如果是大企业或者成熟的团队,可能需要考虑的因素就更多一点。
另外一个值得注意的问题是,Selenium之类的自动化工具有的是支持录制屏幕和操作的。如果能用录制而不是编程的方式来创建自动化测试脚本,则又可能省掉一些时间。
在实践中,我们是要求项目组自己探索一个合适的自动化测试方式。我们也建立了一些工具帮助项目组。比如我们用SonarQube来分析单元测试覆盖率。虽然我们没有对覆盖率做强制要求,但我们隔一段时间会让项目组一起在对SonarQube的报告做一些分析,找出哪些方面写单元测试可以取得最大的效果/时间比。
流程改善之改进团队协作
前面提到的协作工具,其实已经涉及到了改善协作的内容。至少改变了沟通基本靠吼的局面。不过团队协作涉及到很多层次的内容。这里总结几点我们觉得很有价值的实践。
需求/计划讨论会议与回顾会议
做软件开发的人很多都不喜欢开会。不过有些会确实有必要。这里有几个开会的要点:
- 避免繁文缛节。领导在会上更多起主持串联和倾听的作用。避免领导在会上说一大堆自己的观点。也避免太多无用的程序。
- 避免会议太过密集
- 避免开大会,尽量只找相干的人开会
- 针对具体的事情进行讨论。讨论过于抽象就不好了。
- 做好会前准备,比如如果讨论的事情大家不熟悉,可以把相关材料早点发送给与会者并提醒阅读
- 给每个人发言的机会。
- 对会上重要的观点要做记录
对于开发团队来说,在一个阶段的开发开始之前,开会讨论一下需求和计划,会有积极的作用。如果需求和计划都很清楚,大家可以简短讨论一下就结束了。而如果有不清楚的地方,不一定非得在会上搞清楚,可以记录下来线下解决(以避免会议过于冗长)。
每个开发周期结束之后,也应该开一个回顾会议,让大家讨论一下哪些地方做得好,哪些地方需要改善。这些意见会成为渐进式流程改进的重要输入。
流程改进之改善设计与代码
改善设计与重构
我们在本案例中采取的实践称之为“轻设计”。也就是在项目初期,由开发团队讨论出一个比较轻量级的设计,这个设计大体包括程序的分层结构和数据交互格式,公用库的引用,事务,持久化以及一些基础类等等。这些设计很快就落实在了代码中,而不需要写太多文档。而在之后的开发中,由开发团队进行持续的改善和重构。
代码和设计的重构都需要时间,而对于很多中小项目来说,时间非常重要也非常有限。因此对于代码质量,设计质量的追求,都要尽量追求在有限时间里取得最好的效果。这方面类似Checkstyle,PMD之类的工具能减少你发现代码问题的时间。
代码风格与质量
而在代码风格方面,最好可以使用一些编辑器的内建自动格式化功能。这可以大大节省开发在格式化代码方面消耗的时间。代码规范最好使用业界流行的规范,比如Java可以用Sun的代码规范,C#可以用微软的代码规范。切忌听一些“大牛”的搞出一套怪异的代码规范。
正如我们前面所说,对于很多中小企业来说,设计/代码质量并不是关系到他们生死攸关的问题,因此优先级可以低一点。但这并不是我们可以什么都不做的借口。通过综合考虑可能付出的时间与收效,制定一个渐进式改善设计/代码质量的计划,并定期对设计/代码质量进行回顾,会让团队变得越来越好。
而且,如果解决了需求,质量和交付方面的重要问题,也就应该考虑改善设计与代码质量的事情了。
至此本文就结束了。在本文中我们借用一个真实的案例探讨了怎么让软件团队从无序走向有序的方法:通过渐进式的流程改进对主要的问题逐个解决。你可能注意到我们没有提到诸如Scrum,UP等具体的流程。这是因为文中的这些原则可以应用在任何一种软件生存周期(SDLC)中。我真心希望这篇文章对您或者您的企业有所启发。
本文较长,感谢您的耐心阅读。如果您都已经花时间读到这里了,就随手加个关注呗。也欢迎您随时留言。再次真诚地感谢。