我很喜欢看各个产品的Bug追踪系统,比如jQuery的Bug Tracker,因为在Bug系统中总能发现一些非常细节的问题,补充自己的知识,慢慢地自己的代码的兼容性会有很大的提高。
但是,在各个Bug系统之中,包括现在公司使用的Trace系统,无一例外地存在一些让我不满意之处,其中最大的原因就是很多Bug系统仅仅是作为Bug的记录系统存在,而没有试图去让一个Bug成为一个知识的积累,让整个Bug系统变成一个丰富充实的知识库。这样的Bug系统,永远都只是提供一个简单的业务流程,不会变成干完人员、产品、甚至是整个团队的进步的天梯。
在我看来,一个Bug系统应该更加全面,管理Bug的生命周期的同时,也用于管理一个产品、团队的知识,更可以与周边系统合作,形成一个真正的集成式管理平台。
Bug的分类
现在的Bug系统,对Bug系统的分类通常有这么几种:
- 根据性质:Bug、Feature、Enhancement等。
- 根据危险程度:Trival、Minor、Normal、Major、Critical等。
- 根据模块、系统、可重现性等与项目紧密相关的分类。
但是这些Bug系统往往忽略了一个很重要的分类方式,那就是“按Bug影响面分类”,在这种分类模式下,一个Bug可以根据其影响的范围来进行区分:
- 项目型Bug
-
与当前项目的业务流程、逻辑等有紧密关系的Bug,此类Bug只可能在当前项目中出现,离开了项目的大环境就没有任何存在的意义。
针对此类的Bug,只需要在当前的环境下修复即可,不需要考虑太多的问题。
- 复发型Bug
-
此类Bug通常也与项目有紧密的关系,但是此类Bug在项目的整个演化过程中一而再再而三的出现,也许每一次出现的原因有些许差异,但表现上极其相似。比如某系统每天下午17:00左右会出现无法提供服务的情况,在第一轮修复的情况下,几周后继续出现此类情况。
在这样的前提下,该问题就应该被评定为复发型Bug。对于复发型Bug,项目管理层及开发人员都应该给予绝对的重视,投入足够的人力和时间来对问题进行彻底的跟踪和追查,以期从根本上进行解决。
同时,在问题被定位并修复后,可以进行一次case study,以杜绝此类问题的再次发生。
- 通用型Bug
-
此类Bug是我认为当前的Bug系统最没有关注到的一个问题,而且相比前面两类Bug往往可以在项目层面通过制度和流程来进行规范,通用型Bug是一个最需要自动化处理的问题。这往往涉及到不同团队之间的合作,也是Bug平台成为一个知识库的最为基础的条件。
顾名思义,通用型Bug即与项目本身的业务没有任何关系的,仅仅是技术上存在的问题。比如我最近发现的一个Bug,其可以用以下的代码来表现:
DOCTYPE html> <head> <base target="_blank" /> <body> <script> var iframe = document.createElement('iframe'); document.body.appendChild(iframe); iframe.contentWindow.location = 'javascript:;'; // 以上代码会在IE9下弹出一个窗口 </script>这个Bug很明显,是不属于任何项目的,即所有项目在特定的情况下都可能使用类似的代码,产生相同的Bug。
在这样的情况下,如果将这个Bug继续划定在某个项目之下,那么他最多只能为一个项目提供帮助,防止该项目再次出现类似的问题。因此我们各项目组间可能经常能看到这样的对话:
A:Hi,我们这边发现一个问题,具体是…………这样的,你们有相关经验吗?
B:哈哈,这个我们前段时间才遇上过,解决方法是…………那样的。A:谢谢,谢谢!!
确实,这样的场景很多,甚至能贯以“项目之间善于交流”的美名,但是如果认真地去思考,这样的场景真的有必要吗?如果有一个自动化的平台,会将这些通用的Bug都公布出来,每个人各取所需进行关注、记录,又怎么会出现这样的对话呢?
交流,哪怕是使用最好的方式进行最有效的沟通,始终是有一定的成本的。同时,交流通常是1v1的关系,即便频繁的接触、沟通,一个知识也很难以广播的形式让尽可能多地需要他的人接收到。
正因如此,我才认为一个Bug系统的职责远不止记录、处理、关闭Bug,而应该作为一个知识的集散地,在团队的发展中起更大的作用。
通用性Bug处理平台
前面也提到,对于通用型Bug,平台应该有能力对其进行分发、通告,在这里再详细地总结一下,一个较为完善的Bug平台,在处理通用型Bug方面应该至少有以下的特色:
- Bug的tag
- 无论系统内置使用怎么样的方式来对Bug进行分类,其分类的维度总会有照顾不周之处。因此在Bug平台中应该引入tag的概念,让每一个Bug都能够有一个或多个tag,使用tag这种通用的方式来标识一个Bug的属性,也进一步方便了灵活的分类。
- Bug的订阅
- 在Bug有了tag之后,所有拥有相应权限的人都可以订阅其指定的tag的通用型Bug。当一个Bug被提升为通用型Bug时,Bug平台会找到所有订阅了这个Bug拥有的tag的用户,并通过邮件等形式向其发送该Bug报告。而随后Bug的每一个处理环节都会有邮件等形式的广播。
- Bug的共享
- 在Bug可以被订阅和广播的同时,通用型Bug应该允许每一个有权限(并且此类权限应该放得很宽松)的用户来参与讨论、修补,每一个人都可以提交解决方案,再由相应的QA进行验证后给予实行。这样的效率远大于一个项目的开发人员独自苦苦挣扎,因为很可能有某个人曾经遇上过这个问题,对他来说提供解决方案仅仅是举手之劳。
Bug的生命周期
当前多数的Bug平台将Bug的状态分为几个阶段,一般是Open -> Resolved -> Closed这样的过程,但这其实远远没有涵盖一个Bug处理过程中应该有的环节。
当然作为一个简单、现实为上的Bug系统,其主要环节有以上三者足矣,但是如果需要将Bug平台扩展成一个知识库,就不得不添加更多的环节,以期得到更多的信息:
- Open,Bug的发现阶段,此时创建一个Bug,通常这个动作由QA进行。任何可重现、不可重现、小频率重现的问题都可以进入到这个阶段。
- Reproduce Step Confirmed,Bug的重现步骤被确定,通常由QA提交。在这个阶段的Bug通常是稳定的,至少通过QA提供的重现步骤能大概率地被重现出来。
- Reproduce Environment Confirmed,Bug的重现环境被确定,通常由开发人员提交。在这个阶段,在正常的重现步骤之外,开发人员已经可以提供一个最简的环境来复现问题,可能是一段非常精简的代码,也可能是一个很简单的步骤,其特点是这个重现的环境远比QA的按步操作来得简单,甚至可能得以自动化的重现。如果问题可以自动化重现和确定,则可以考虑将自动化脚本作为单元测试保存。
- Reason Found,问题的根本原因被确定,通常由开发人员提交。在这个阶段,开发人员需要描述问题产生的原因,可能是某个业务逻辑的理解有分歧、或者某个第三方产品确实存在Bug、或者某段代码存在着函数使用的错误等。
- Resolution Submitted,解决方案已提交,通常由开发人员进行。在这个阶段,开发人员提交一个完整的解决方案,根据开发人员的思路,这个解决方案确实得以修复该问题。随后同项目级的人员、QA可以对该解决方案进行评估,确定对其他模块不会有影响等。
- Resolution Applied,已经应用了解决方案,通常由开发人员提交。此时开发人员指定一个新的源码版本号,该版本号中的相应代码段应用了第5步中提交的解决方案,问题应当已经修复。
- Resolution Confirmed,问题已经确定修复,由QA人员提交。此阶段QA确定问题已经被修复,并且经过了一定范围的回归测试,确保问题不会对其他模块产生严重影响。在这个阶段,Bug依旧是开放状态,各成员可以对Bug进行参与,作一些总结性的讨论。
- Close,Bug关闭,此时Bug已经锁定,可以作为一个固定的知识项来查看,但不再有修改和讨论的可能性。
以上为一个非常周全的Bug生命周期管理,但确实不需要对其进行一个强制的要求。一个Bug平台可以提供这些生命周期,也许只是简单地在“Bug状态”中添加相应的项,而进一步如何引导用户对这些环节进行充分的利用,则可以通过团队的规章、Bug平台本身的界面等方面来进行,强硬地规定只会让Bug追踪过程事倍功半。
其他方面的增强
上文提的是个人认为Bug平台向知识库整合过程中最重要的一环,即通用型Bug的分类、分享、订阅工作,以此为其他来散布众多点状知识,以期通过所有人员共同参与交流、沟通,再将点状的知识整合成线状甚至是面状的知识体系,补充团队的经验和能力。
但是在此之外,其实Bug平台还可以做很多事情,来提高这个“伪知识平台”的使用体验,证知识更加有条理、有结构:
-
与源码平台关联
一个Bug平台应该与源码平台有着非常紧密的关系,包括一个Bug在哪个版本(A)发现,在哪个版本(B)修复,并可以通过平台找到源码平台中两个版本的diff,比如scm.xxx.com/diff?file=abc&rev=A:B。这要求Bug平台与源码平台都提供相应的接口,可以在两个第三方系统间进行交互合作,现时也要求Bug平台有一个严格的规范,在Bug的open和close操作中提供相关的版本号。
-
与知识平台关联
Bug是知识的来源,那么Bug提供的知识自然要进入到知识管理平台。这一点需要系统的智能化识别,当一个Bug其信息足够完善,包括了前面提到的Bug生命周期的各个环节应有的信息的时候,Bug平台应该主动与知识平台连接,将这个Bug整理成一份真正的知识文档进入到知识管理平台。