与生物学的昆虫不同,软件的缺陷要经历一组非常严格的状态(参见图8-2)。在VSTS中,缺陷所允许的缺省的状态和转换依赖于你为项目所选择的过程模板。所选过程的那组规则决定了:选择可允许的状态;定时、授权哪些用户组可以将缺陷推进到下一个状态;允许转换的原因。如果有权限的话,你可以进一步定制这些规则,从而使它们与团队的工作流相匹配。
图8-2此状态图是用于CMMI过程改进的MSF中的软件缺陷的生命周期
在VSTS中
- 在用于CMMI过程改进的MSF中,缺陷有4个状态,开始状态是已提出状态。在变为活动状态之前,需要有个接受操作。
- 在用于敏捷软件开发的MSF中,缺陷只有3个状态,开始状态是活动状态。
任何人都可以提出缺陷,也就是说,请求把它纳入待修复的队列。
项目经理可以激活一个缺陷,然后把它分配给一个开发人员。
在研究或修复了代码后,开发人员会在下一次签入时把缺陷标记为已解决状态(参见图8-3)。不允许开发人员直接关闭缺陷。
图8-3 在VSTS中,很少在check In对话框中核对缺陷,开发人员把将交付的变更集与待修复的缺陷相关联。这种关联是永久的,用于填写构建报告和度量元仓库
当相应的源代码被签入时,签入过程自动解决了缺陷。
测试人员可以在相应的查询中看到已修复的缺陷。只有在测试人员确认缺陷通过了测试从而证明它已被修复之后,才能由测试人员关闭缺陷(当然,如果测试失败了,测试人员就会重新激活缺陷)。
实际上,工作流可能更简单也可能更复杂。例如,在敏捷MSF中,不要求在激活之前必须有个已提出状态,也不强制使用不同的权限,反而要依靠信任。反过来,一些过程,尤其是在后期迭代中,在代码被评审之前,不允许签入代码。工作项可以通过一个新状态或者一个单独的字段来强制这一规则,签入政策可以强制这一工作流。
无论这些规则是什么,它们都是你当前项目的过程的可触摸的形式。
8.2.1报告缺陷就像写新闻
凯列班有个故事讲的是他最喜欢的缺陷。故事大概是这样的:
我一个月前在实验室中发现了这个缺陷,然后报告了它。没有人注意到;所以在优先分配中,他们把它标记为被“推迟”。上个星期我们最大的客户也发现了它,突然之间,这个缺陷就引发了一场危机。现在,我们需要交付一个维护版本,这就意味着我要整个周末都呆在实验室里检查所做的修复。为什么他们在我第一次报告的时候没注意到这个缺陷呢?
真正的原因是什么呢?最常见的原因就是缺陷报告写得不清楚,没有把影响充分传达给优先分配小组,所以所报告的缺陷被关闭了。凯列班的经理普洛斯彼罗对于凯列班的故事则有着不同的看法:“为什么凯列班不能把他的缺陷报告写得清楚些,足以让团队能够对它们有所行动呢?”(因此,和前面一样,普洛斯彼罗在他的下一个项目中没有选择凯列班。)
从凯列班的经验中得出的教训可以用Kaner、Bach和Pettichord的名言来总结:你的主张驱动你所报告的缺陷的修复
你所写的任何一个缺陷报告都是一个呼唤修复此缺陷的宣传文档。
有的缺陷永远也不会被修复。你的责任不是去保证所有的缺陷都被修复了。你的责任是以一种能让读者理解问题全部影响的方式精确地报告缺陷。
你研究得好不好,报告写得好不好,这些通常都会对缺陷修复的概率有着很重大的影响。
详细描写缺陷就像是写新闻报道(或者网页)。它是新闻学。标题就像是头条新闻,你应该希望大多数读者从来也不看“下面的内容”。新闻记者的6个基本问题:什么、哪里、怎么、谁、为什么和什么时候,需要在一两句摘要中都能覆盖到。
了解你的读者
你的缺陷报告的第一个读者就是优先分配小组(优先分配已经在第4章中讨论过)。他们会看到一个看起来像图8-4那样的查询。
图8-4要持续关注读者在优先分配时看到的是什么。读者所看到的并不是所有的细节,他们仅能看到那些适合查询结果列表的内容。你应当根据缺陷的显示格式编写缺陷
优先分配小组中包括了项目中最忙的人。通常他们都只花不到1分钟的时间来评审每个缺陷(每日进行优先分配的一个重要原因就是为了保持列表的长度,从而使每个工作项都能获得它们所应获得的关注)。在那个时候,你的缺陷报告的命运也就注定了和凯列班的缺陷报告的命运一样。如果凯列班能够在缺陷报告的质量上再多花一点时间的话,他的工作价值(和他的绩效打分)就能提高很多。
从历史中学习
阅读缺陷报告,尤其是在它们已经被优先分配之后阅读它们,是向你的项目和读者学习的一个好办法。优先分配的审计会议是另一个方法,你了解到在实践中什么对于涉众是重要的。下面是一些在使用你的缺陷数据库时的提示:
- 执行你感兴趣的缺陷的重现步骤。这是一个很好的方法,你能够从中学习到受测软件的一些更有趣的情形(还能学习如何编写清晰的步骤)。
- 阅读注释,注意其他团队成员是如何回答缺陷报告的,从中学习他们认为什么重要以及如何改进你的报告风格。
- 研究已关闭的缺陷报告,注意从缺陷报告的方式来看,哪些缺陷被修复了,哪些缺陷没被关闭,基于它们被报告的方法。如果希望你的缺陷也被修复,那么就要像历史上的那些得到修复的缺陷那样报告缺陷。
- 如果你在做一个已有的解决方案,应该阅读技术支持日志,查看其中记载的应检查的错误和支持你的缺陷的故事。
SOAP:一个来自医学的类推
软件领域借用了医疗实践中的“优先分配”这一术语,因此看一下它用于医疗时的情景也是合适的。医学人士掌握了一个描述临床报告的首字母缩写SOAP(它与Web服务无关)。这是从马里兰大学药学学校的医学课程提纲中的摘录:
对于每个病人……护理问题(一个或多个),应写进展注释(以SOAP格式),并且应包括以下内容(参见图8-5)。
图8-5在思考表格和健康交谈历史的字段时,SOAP记忆法是个有用的方法。标题(Title)和症状(Symptom)是主观信息(S);发现的构建版本(Found
In \[Build\])、发现的环境(Found-in Environment)和重现步骤(Steps to Reproduce)等字段是客观信息(O);优先级(Priority)、严重程度(Severity)、区域路径(Area
Path)和根本原因(Root Cause)是评估(A),而迭代(Iteration)和修复(Fix)是计划(P)
主观(Subjective)信息:支持所确定的问题的主观信息;
客观(Objective)信息:支持所确定的问题的客观信息;
评估(Assessment):对于问题的评估,包括病源、严重性、当前治疗的高效性/毒性、治疗学上替代方案的列表、每个方案(治疗学上和经济上)的优点和缺点的讨论以及推荐的根本原因;
计划(Plan):对所确定的问题进行管理的计划,包括实现和后续对问题的监控和治疗学响应的特定大纲。
好工匠会观察其他好工匠(包括其他学科的工匠)做什么。在你报告缺陷和评审缺陷报告时,SOAP是一个应当使用的好模型。让我们看一看VSTS在用于CMMI过程改进的MSF中所提供的标准缺陷报告表单。
8.2.2主观数据
对报告的读者而言,最重要的问题是:对用户的影响是什么?大多数时候,回答这一问题,需要进行一番思考。问自己一些与下面这些问题相类似的问题:
- 当客户看到这一问题时,他会对产品支持人员说什么?
- 根据客户对其他软件(包括竞争者的产品)的体验,这次他们将有什么样的期待?
- 如果销售代表或培训师在演示时遇到了这种情况的话,会说什么呢?
- 这一缺陷会对应用场景产生什么样的影响?
- 这一缺陷会对下游环节产生什么样的影响?
- 会涉及多少用户,频繁程度如何?
- 这是一个孤立的事件吗?
- 这里有安全性的风险吗?
- 其他服务质量会受到影响吗?
首先要编写这个故事。你对这些问题的答案将会决定应花多少时间来研究这一缺陷,又会决定应为此报告收集什么样的数据。
标题问题
正如你在图8-4中所看到的,标题通常是读者所看到的唯一信息。如果标题不清晰,当被截断到适合字段宽度时,信息的剩余部分可能永远也不会读到。
描述困惑
关于缺陷的永久的下一级信息是描述。变更历史可能会很长,但是描述应当是关于缺陷的、简洁的细节。
每个缺陷一个报告
如果你有2个缺陷,就应该写2个报告。保持每个观察到的缺陷都在它自己的报告中,这会让所有报告都更易于理解。
8.2.3 客观数据
在编写了关于此缺陷的主观数据之后(参见图8-6),就到了收集客观数据的时候了。
图8-6这里所说的缺陷工作项类型,来自于用于CMMI过程改进的MSF,它捕获了用户在查询、跟踪和分析缺陷时所需要的所有信息
服务质量
要清楚你所报告的问题的类型——服务质量受到了什么影响。
相关特性或代码
如果你能把缺陷与你所测试的特定特性或受测源代码的特定区域关联起来,那就这么做。
重现测试
如果你有一个测试来重现这个缺陷,那就标识出它。
附件
你可以附加什么样的数据到缺陷报告上,从而演示这一缺陷发生在怎么样的条件下?如果适用的话,所有这些都会有用的:
- 屏幕快照
- 数据文件
- 配置文件
- 跟踪文件
- 服务器日志
- Dr.Watson日志
重现步骤
你如何在最小的设置中以最少的步骤来重现这一缺陷?在开发者针对缺陷的工作中,80%的工作量往往就在于重现步骤——你能把缺陷发生过程简化到什么程度?任何不必要的东西显然都是浪费。要确保重现步骤精确和清晰。在提交缺陷之前,要检查它们。
前置条件
重现这一错误,比如加载一个特定的数据库,是否需要特殊的设置?如果问题能够通过产品数据或客户数据演示出来,这就特别有说服力。
8.2.4评估数据
在缺陷的生命周期中,评估会发生多次变化,因为人们需要精细化诊断和观察、调试源代码、努力修复和测试修复、研究相关的缺陷等等。你的任务就是要保证缺陷历史的精确性和全面性,因为对于缺陷及其条件你所知甚多。
在初始报告中,你能够做一些评估,而更多的评估会随着缺陷的历史和会话而演进。
它是不是重复的
应花一点时间查询整个数据库,从而确定这到底是关于已发现缺陷的更多的信息呢,还是一个新发现的缺陷。但是不要过分沉迷。稍后别人将你报告的缺陷标为重复,这也很容易。显然,如果你发现了关于已有的缺陷的更多信息,就应该把发现更新到该缺陷报告中。
它的一般性如何
去除你的边际情形(corner case)的边际性。通常,你会使用极限数值、不常见的配置或者长输入序列来发现缺陷。理解缺陷重要性的根本就是要知道缺陷发生所必须的特殊性条件或一般性条件。这里是一些提示:
- 使用不同的数据。如果你是用一组特定的输入值发现的缺陷,那么就尝试一下不同的输入值。尤其是要尝试不同的等价类。缺陷的表现对特定值或特定等价类的依赖程度如何?
- 使用不同的配置。如果你是在硬件和软件构件的一个特殊配置下发现的缺陷,那么应该在一组非常不同的机器上试一下。
- 使用不同的流。如果缺陷出现在一个特殊的操作序列(尤其是很长的序列)下,那么看看是不是有其他(最好是更短的)路径可以得到同样的结果。
- 寻找可疑的交互。如果有的事情好像是一个奇怪的副作用,但你又不确定,要继续刺探。例如,在你使用了一个程序之后,另一个可能突然变慢了。可能它们依赖一些相同的部件、数据或者OS服务。
- 还有更多的吗?猜测类似的缺陷还会潜伏在哪里。寻找它们。
它的严重性如何
当你第一次发现一个缺陷时,会有一种巨大的诱惑让你感到满意并要报告它。实际上,可能还有很多更严重的问题。注意初始的症状并继续使用受测软件。你可能会发现没有被妥善处理的错误路径和异常,以及未预料到的交互和其他会给用户(或技术支持人员)造成困惑的问题。
8.2.5 计划
在初始报告中,你手中主要的计划工具是优先排序和归属关系。根据你的不同过程,这些可能只能由优先分配小组来设定,或者在不太正规的组织中,也可能由提交者直接填报。处理优先排序的方式应当与它在项目管理中所采用的方式相同。
迭代
仔细考虑计划中的迭代。在早期迭代中,所提出的缺陷往往都集中在那些现在还不能工作的功能上。优先分配的目的之一正是从开发人员的直接队列中清除这种噪音。
8.3 小结
本章关注缺陷的报告。显然,正如前面几章中都讨论过的,应使用良好的需求、架构和开发实践来防止缺陷发生,这比发现缺陷然后承受必要的返工来修复缺陷要好得多了。尽管如此,缺陷总会发生,因此每个发现缺陷的人都应当捕获缺陷的细节。
在编写缺陷报告时,要了解你的读者。你的大多数读者会只看标题,并且所看到的标题可能是被截取后的标题。努力做到让标题清楚地概括了缺陷的影响和重要性;否则,其余的信息就可能会被忽略。
在完成报告的其余部分时, SOAP(主观-客观-评估-计划)是一个很有用的记忆法,这是一个从医疗领域借用来的术语。特别是这种对医疗的模拟不仅能够帮助你努力地思考评估和计划,还能帮你不再把缺陷想成一个数字游戏。
|