程序错误分析(编写表达BUG报告)
55)错误报告,文如其人。
56)好的错误报告,能推动错误的改正。测试员的责任不是保证所有错误都得到改正,而准确报告问题,使读者能够理解问题的影响。
57)使自己的错误报告成为一种有效的“销售工具”。因为错误报告劝导人们付出宝贵资源来换取测试员所建议的好处。对于程序错误,资源就是时间和资金,好处就是通过改正这个错误而带来质量改进。销售策略一般有两个目标:其一:陈述种种好处,使得潜在客户想要它。其二:向销售人员说明预期存在的问题,并反驳他们。
58)错误报告代表的是测试员。
59)努力使错误报告有更高的价值。例如:
报告缺陷,并帮助程序员定位内部问题。
报告规格说明、测试文档、用户文档或开发工具中的问题。
为技术文档编写员提供背景信息,编写员要编写手册或公司网站中的问题定位部分。
报告提示需要通过客户培训解决的问题。
报告为客户售后支持人员提供关键信息,如他们会遇到哪些没被解决或不完全解决的问题。
报告和管理员提供正在开发的产品状态和质量信息。
报告在开始计划产品下一个版本时,提供初始改进建议。
60)任何产品/项目的相关人员都应该能够报告程序错误。
61)引用别人的错误报告时要小心。注意:一方面:如果没得到允许,可以补充评论,但不能编辑别人的材料,即使错误报告很糟糕也不要擅自修改因为很可能会遗漏重要信息的风险;另一方面,任何时候要在(特别是其他人的)错误报告做补充,都要注明自己的姓名和日期。
62)将质量作为错误报告。(质量对于个人来说就是价值。)测试员的任务就是帮助项目相关人员写出清晰的其对产品感到没价值的意见。
63)有些产品/项目相关人员不能报告程序错误,测试员就是他们的代理,所以应站在他们的立场理解要报告的内容。例如:测试员必须研究用户使用产品的方式,以及他们喜欢这种产品的什么,不喜欢什么。
64)将受到影响的项目相关人员的注意力转移到有争议的程序错误上。例如:如果测试员认为很难说服程序员改正错误,但是测试员希望改正,可以考虑公司中如果这个错误被改正能够受益的其他人。
65)决不要利用BUG管理系统监视程序员的表现。例如:使用该系统估算修改代码的时间,这样会使程序员感到为难外,其他程序员也就防备这个系统,最有可能的结果是,程序员争辩设计问题并不是程序错误,类似的错误是重复的等。
66)决不要利用BUG管理系统监视测试员的表现。例如:如果测试经理用BUG数作为考核依据,测试员也许会报告容易发现、更肤浅的BUG,也许更愿意报告同个BUG多个实例;他们会不愿意花时间指导其他测试员;程序员更有可能认为测试员是为了BUG数而不质量。
67)及时报告BUG。因为BUG报告拖延的时间越长,BUG被修复的可能性就越小;另一个风险是:项目其它相关人员就错误地以为已测功能点没BUG很稳定。
68)永远不要假设明显的BUG别人已提过。
69)测试员应报告设计错误。
70)极端的缺陷是潜在的安全漏洞。
71)使冷僻用例不冷僻。例如:极值测试思想:如果程序能够在这种条件下存活,那么在不那么极端的情况下也可以存活。因些可以通过少量极端测试了解很多东西。
72)小缺陷也值得报告和修改。Kaner和David Pels研究发现小缺陷(指修改BUG在4小时以内的BUG)修改可避免该产品一半以上的技术支持成本。
注意:任何产品都会残留一些小缺陷。但随着小缺陷数量增加,客户信心会下降,更糟糕的是容忍这些缺陷的腐蚀作用。当连报告小缺陷的行为都停止后,测试员和公司就会容忍越来越多的严重缺陷,长此以往,最终会使产品失败。
73)时刻明确严重等级和优先等级间的区别。严重等级:指BUG的影响或后果;优先等级:指什么时候要求修复。
74)失效是错误征兆,而不是错误本身。因此,任何时候看起来很小的错误,都要:执行后续测试,以发现更严重的征兆或以发现更一般的场景。当问题很难重现时,可执行后续测试,以确定使该问题重现的关键条件,然后执行后续测试,以充分暴露现在已可重现的问题。
75)针对看起来很小的代码错误执行后续测试。如果看到的是小失效,不要只是重现该失效并写入报告。程序处于脆弱状态,尝试利用这一点,继续测试,并可能发现内部缺陷的实际影响是糟糕得多的失效,例如系统崩溃或数据损坏。
对于每个认为反映了编码错误的失效至少要做几分钟的后续测试,要相信自己的判断。建议尝试如下三种后续测试:
a变化自己的行为。(通过改变操作方式改变条件)
b变化程序选项和设置。(通过改变被测试对象的条件)例如:使用不同的数据库,改变持久变量的取值等。
c变化软件和硬件环境。注意:这不是配置测试,不是要检查标准配置上的缺陷,而是要调查怎样变更配置才会使这个失效暴露充分。
76)永远都要报告不可重现的错误,这样的错误可能是时间炸弹。注意:不要报告还没尽力重现的程序错误,但如果尽力之后仍不能重现该程序错误,仍值得报告,不过要明确说明自己不能重现这个程序错误。
77)不可重现的程序错误是可重现的。如下是无法重现时需注意的关注点:
a程序错误可能有延迟效应,例如内存泄漏、指针越界。
b程序错误可能只是在安装、使用产品或使用产品的特定功能时出现一次。恢复干净系统,重新装载该程序,检查现在是否能够重现该问题。
c程序错误可能依赖于特定的数据取值或被破坏了的数据库。
d程序错误可能只在特定的时间或日期内发生。检查日末、周末、季度末、年末。
e缺陷可能依赖于以特定顺序执行一系列相关的任务。在执行这个失效任务前做了什么?
f程序错误可能是前面失效的残余。例如:上一次出现GPF后重新启动计算机了吗?
g程序错误可能是由被应用程序与后台运行的其他软件,或与被测试应用程序竞争设备访问软件的交互引起的。
78)注意缺陷报告的处理成本。
79)特别处理与工具或环境相关的程序错误。
80)在报告原型或早期个人版本的程序错误之前,要先征得同意。注意:在正式测试时,要把以前发现但仍没被修复的问题录入BUG管理系统。
81)重复错误报告是能够自我解决的问题。注意:
a不要让搜索时间失控。如果BUG数据库大,可能需花大量非生产时间搜索重复程序错误。
b编写良好的相同BUG的所有报告都包含新信息,有助于更容易修复BUG。
c两个报告是否重复还需再统一确认。两个失效可能是由同一个缺陷引起的,多个缺陷可能涉及到一个失效。要保留所收藏到的所有信息,直到确认统一并修复了该BUG。
82)每个程序错误都需要单独的报告。Pettichord另一种建议:
有时为了提高效率,可以在一份报告中包含多个相似的小BUG,假设这些BUG可以一次全解决。如果这个问题单状态标记为已修复后,仍有没修复的残余BUG,可以为这些没修复的BUG写一份新报告,并引用已修复的老问题单号。
83)BUG标题是错误报告中最重要的部分。建议包含的内容:
a简要描述,要足够具体,使读者能够想像出该失效。
b简要指出程序错误的局限性或依赖关系。例如:BUG产生的环境局限。
c简要指出程序错误的影响或后果。
84)不要夸大程序错误。记住,测试员的可信性是影响力的基础。
85)清楚地报告问题,但不要试图解决问题。
86)注意自己的语气及报告的格式。例如:全部采用大写字母,则读起来像是编写报告者在尖叫。
87)使自己的报告具有可读性,即使阅读对象是劳累和暴躁的人。要使重现步骤的描述简洁:
a一次只走查该程序错误一步。
b为每一步编号。
c不要跳过重现问题所需的任何步骤。
d尽量写出能重现的最少步骤。
e通过空行使报告更容易浏览。
f使用简短句子。
g说明实际发生了什么,自己预期会发生什么。
h如果后果很严重,可解释为什么自己认为很严重。
i便于程序员意识到问题或便于自己回归测试,可补充注释。
j对于复杂产品或问题,考虑使用描述的头三行专门小结问题,然后给出问题细节。
k要始终保持中立语气。
l不要开玩笑,别人会产生误解。
88)提高报告编写技能。研究BUG管理系统的BUG,找出提高报告编写技能的思路。例如:
a比较已修复的BUG和未修复的BUG,研究两都报告方式的差别。
b研究程序员对错误报告的反映。例如:什么使他们困惑不解、不能接受、能够接受?
89)如果合适,可使用市场开发或技术支持数据。例如:
a可与同行产品进行比较,有助于描述用户预期及有助于市场开发经理评估问题的严重等级。
b调查市场与客户接触时都遇到什么问题,他们如何说明产品,演示什么,怎么演示,在报告中使用调查结果。
c如果可能,将报告的BUG与相关的技术支持记录联系起来。可估计延迟修复BUG的技术支持成本或如果BUG留在产品中将会面临客户或技术支持人员的不满。
90)相互评审错误报告。例如:在提交给程序员前,要安排第二个测试员评审所有报告缺陷。第二个测试员要:
a检查是否清楚地提供了关键信息。
b检查是否可重现该BUG。
c研究该报告是否能够简化、概括或加强。
测试员可以评审:所有缺陷、自己发现的所有缺陷、同事发现的所有缺陷。如果发现报告有问题,可找报告提交人讨论该BUG。
注意:这是一种培训员工、提高报告质量的有用的方法,但注意不要过多地增加评审测试员的负担。评审过程需时间。
91)与将阅读错误报告的程序员见面。
92)最好的方法可能是向程序员演示所发现的BUG。
93)当程序员说问题已经解决时,要检查是否真的没问题了。
94)尽快回归已修复的BUG。
因为尽快回归已修复BUG,一方面,可表现出对程序员的尊重,也使程序员将来更有可能对测试员所报告的BUG迅速做出响应。另一方面,程序员可能仍然记得自己是怎么改的代码,并能够立即处理该问题。
95)如果回归不通过,应与程序员沟通,而不仅仅通过报告反馈信息。测试员与程序员沟通时,语气和态度应该友好、热心。测试员要帮助程序员立即得到信息,并准备随时澄清报告中的任何不清楚的地方,如果程序员想看,应准备随时演示该BUG。
96)错误报告应该由测试员关闭。一般情况下,报告该BUG的测试员应再次进行测试,但是如果程序错误是非测试员报告的,是应由最熟悉程序这部分的测试员进行评估,如果可能,该测试员也应该咨询原始报告者沟通。注意:除非经过测试员的评审和关闭,否则任何BUG都不能标识为已关闭。
97)不要坚持要求修改所有BUG,要量力而行。注意:如查不能举出某个BUG很重要,或产品/项目相关人员有充分支持测试员关于推迟特定BUG修复的请求,我们建议还是把该BUG放在一边,先考虑其它问题。
98)不要让延迟修复的BUG消失。建议:在项目一开始时评审延迟修复的BUG,因为此时进度压力最轻,而且项目经理也处于最清醒、最理智的状态。
99)测试的惰性不能成为BUG推迟修复的原因。
注意:如查测试经理要求程序员不要修复该BUG,而原因仅仅因为修复该问题会影响太多的检查单、脚本或其他测试用例,因此要占用太多的管理时间,那么说明测试过程存在致命缺陷。
100)对BUG延迟修复应立即上诉。
101)如果决定要上诉,就一定要赢。
注意:如果测试员确实要上诉,不要依赖自己最初错误报告中的语言和信息。如果测试员不列举出更有效的例子,则不仅是浪费自己的时间也损害自己的信誉。为了准备自己的上诉,测试员需提前做到如下几点:
a与其它产品项目相关人员沟通。找出如果BUG留在产品对其影响最大的人,确定该BUG会增加他们多少成本或给他们带来多大麻烦。
b补充做一些后续测试,寻找更严重的后果或寻找更广的环境下产生。
c创建一些场景,说明合理的用户在合理地使用该产品时也会遇到该问题。
d寻找一些讨论与所报告错误类似问题的报刊文章。如:同行交付类似问题的产品后带来的后果。
测试自动化:
如果自动化能促进测试使命的完成,就利用自动化。评估利用自动化是否成功的标准,是看它在多大程度上帮助测试员完成自己的使命。
测试自动化注意点:
a在决定要自动化的内容时,首先设计自己的测试。这样可避免落入自动化测试的陷阱:易于自动化,但在找缺陷上很弱。
b采用与设计手工测试不同的方法设计自动化测试。例如:自动化时需考虑考虑人所不能做的事。因为在设计手工测试时,测试员不太可能考虑如数千文件重复进行的测试,只因工作量太大。
总结为两点:
a没有好的测试设计的自动化可能会产生大量活动,但没什么价值。
b没很好理解自动化可能性的测试设计,可能会低估一些最有价值的自动化机会。
102)加快开发过程,而不是试图在测试上省钱。
即如果要得到支持,就要把精力集中到降低开发失效的风险上。例如:迅速找出新版本中不稳定的变更;尽快暴露回归结果;快速报告问题。
其中,支持加快开发节奏的手段有:自动化冒烟测试、自动化单元测试。
冒烟测试:这个词来自硬件测试。测试员插入一块新板子并接通电源。如果看到板子冒烟,立即切断电源。不必再做进一步的测试。冒烟测试又叫“版本确认测试”在有限的时间内,快速测试产品的功能。如果关键的功能不能正常运行或重要的BUG回归不通过,测试员就不再浪费时间安装或测试该版本。
103)拓展测试领域,不要不断重复相同的测试。注意:利用自动化拓展测试领域,使测试员能够看到更多、做到更多。
自动化测试可拓展如下的测试范围:负载测试、性能基准测试、配置测试、耐力测试、竞争条件、组合错误。
104)根据自己的背景选择自动化测试策略。自动化测试策略受测试需求、软件产品体系结构、测试人员技能。
测试需求:系统中往往只有少量的功能是关键的,且会被要求将其自动化;另一方面关注自动化能如何帮助控制产品的主要风险。
软件产品体系结构:分析产品体系结构以确定测试自动化的可能性。例如:主要软件组件是什么?这些组件如何通信?使用了什么技术?有哪些可用接触点?组件间的关系。即,语言、环境和组件都会影响测试工具的适用性。
测试人员技能:因为有些自动化测试方法适合没编写程序能力的测试员,有些则对编写程序能力要求较高。
105)不要强求100%自动化。
106)测试工具并不是策略。注意:工具不能教测试员如何测试,如果测试出问题,则测试工具会加重问题。在实现测试过程自动化前,应首先解决测试过程中的问题。
107)不要通过自动化测试使无序情况更严重。如果测试设计得很差,则自动化会使差的测试执行得更快;如果测试组织得很差,计算机并不会替人组织,且自动化测试会把人的注意力从真正需要做的工作移开。
108)不要把手工测试与自动化测试等同起来。
因为自动化测试只能执行测试员明确描述的测试,而不能利用测试员隐含的知识和认识。经过专业培训的人大脑是最好的测试工具,要超过任何可能的自动化测试工具。
109)不要根据测试运行的频率来估计测试的价值。因为测试价值在于它所提供的信息,自动化测试的价值是成本和效益综合分析。注意:测试本身是不可比较的,因手工测试和自动测试不能提供相同类型的信息。
110)自动化的回归测试发现少部分程序错误。非正式调查显示,回归测试发现BUG数占总数的15%,而老功能的新测试一般能发现接近30%~80%的程序错误。
111)在自动化测试时考虑什么样的程序错误没有发现。在计算测试自动化的成本时,建议关注机会成本。考虑花在自动化的时间可用来做什么呢?现在没运行什么测试?没发现什么BUG?
112)差的自动化测试问题是没有人注意。例如:自动化测试包是以前创建的,现在仍用来测试该产品。此时需注意:该包可能并不能完成所想像的工作;测试可能已不再重要;覆盖率可能很差;虚警可能很常见;测试结果可能有错。
好的测试包是活的。要补充新测试,要修复或删除老测试。如果没出现这种情况,测试包就会开始僵化。不久开发人员就会转到其它工作上,测试包就会开始进入神话般的老橡树状态,即动画片中的那种给出建议的角色。慢慢地,因为它已存在很长时间,我们盲目相信创建了出色测试包的老测试员的智慧和编码的现象叫做老橡树综合症。
113)捕获回放失败。关键问题是,这种录制回放工具的脚本与用户界面和系统配置的微小细节捆绑得太紧,只要程序或设计一改,这些测试就不能再用了。所以我们建议:要在构建能够持久或与手工测试结合的自动化测试的技能和规划上投入,与录制回放相比,这两种测试更高效。但录制回放工具对学习工具很有用,并有助于手工编辑测试脚本,我们反对将录制回放单独做为解决方案。
114)测试工具也有程序错误。
115)用户界面变更。保持与用户界面设计变更同步,是GUI自动化测试的一个主要困难,如果要自动化GUI测试,需把这点考虑在内。另,我们要抽象测试自动化设计的界面。即当用户界面变更时,只需升级抽象层,而不是升级访问修改后界面的所有测试。以下是提供产品GUI抽象的一些手段:
a窗口映射:GUI测试工具支持各种手段来标识窗口控件。例如内容名称、各种属性、邻近标签和顺序位置。注意:不是将标识手段嵌入到对控件的所有引用中,而是使用窗口映射名称与该控件的标识手段关联。如果用户界面变更迫使变更具体手段,则只需更新窗口映射。
b数据驱动的自动化测试:使测试员变更测试过程后仍能使用之前所创建的测试数据。
c任务库:将测试用例分解为要素任务。每个任务在概念上都应该是不同的。要特别注意任务的起始和结束状态。为这些任务创建可以在测试脚本中使用的函数。如果任务的用户界面出现变化,只需更新任务而不用更新任务的测试。
d关键词驱动的自动化测试。
e基于API的自动化测试:完成避免GUI。
116)根据兼容性、熟悉程度和服务选择GUI测试工具。需考虑的因素,例如:确定团队已知的工具或已知的工具所使用的语言(因为工具使用培训和学习费用相当高);提供商支持工具的能力;需花一段时间测试工具与产品的兼容性,并检查提供商的服务记录,要有一个试用期(30~90天),或至少30天的订金返还保证。
117)自动回归测试消亡。自动化回归测试不能使用的时间比期望的要早得多。很多自动化测试开发人员都发现,在诊断测试失效和修复退化测试方面所花的时间太多。所以失控的维护成本也许是自动回归测试要解决的最常见问题。
118)测试自动化是一种软件开发过程。测试自动化项目常由于缺乏约束和项目管理而失败。具体建议做到:规划项目,并建立里程碑和可音乐会制品,定义需求,对工具、自动化代码和测试进行源代码控制;在编写代码前先设计并对代码进行评审和测试;跟踪自动化程序的BUG;将自动化测试的使用写成文档并提供给非自动化开发人员使用。
119)测试自动化是一种重要投资。注意:不要把测试自动化的所有预算都投到测试工具上,那只是冰山一角。
120)测试自动化项目需要程序设计、测试和项目管理的技能。
121)通过试点验证可行性。例如:计划用一个月左右的时间显示结果,然后全面推广。
122)请测试员和程序员参与测试自动化项目。考虑关键域,确立清晰的目标并定义需求:
a可评审性:谁评审测试?做到这一点难度有多大?
b可维护性:谁将维护测试?他们必须了解什么?
c完整性:怎么知道测试被别人信任?
123)设计自动化测试以推动评审。
--124)在自动化测试设计上不要吝啬。
自动化测试设计需明确考虑的问题:
a保证测试已被正确地设置。
b描述预期结果。
c发现潜在的错误和副作用。
d从潜在测试失效中恢复。
e防止测试相互干扰。
125)避免在测试脚本中使用复杂逻辑。当需要复杂的逻辑控制时,可把逻辑放在单独的功能中,这样也可以单独测试该功能,也使测试更容易评审。注意:要使测试简单,使测试线性化。
126)不要只是为了避免重复编码而构建代码库。因为使用这种库的测试很难评审、调试、修改。有用的库应该遵循更强的设计原则,应关注封装用户可感知到的任务,特别注意函数的起始和结束状态。这种工作并不总能达到目的,如果出现这种情况,可采用“开放编码”方法。(即,保留重复代码不动)。
127)数据驱动的自动化测试更便于运行大量测试变种。这种方法对于有很多不同数据选项的产品工作流来说最有效。
--128)关键词驱动的自动化测试便于非程序员创建测试。
关键词驱动的自动化测试建立在数据驱动手段上,但是表中包含指令(关键词),而不只是数据。
关键词驱动的自动化测试实行步骤:
a这种方法既要求支持运行测试,又支持设置库、结果分析和报告的一般框架。
b必须创建一个任务库,封装被测产品支持的用户任务。标识可在测试中使用的所有任务函数,对每个任务函数在任务库中都有一个记录与之对应。声明任务函数有效的起始状态,以及所产生的结束状态。这样可以分辨出哪个任务函数序列有效,以便捕获有问题的测试。
c增加对读取电子表格数据的支持,每次读入一行。通过声明把第一列解释为任务函数的名称,后续列是函数的参数。使用函数的参数执行该函数。然后指向下一行。
129)利用自动化手段生成测试输入。在以下情况有帮助,例如:
a创建大文件。
b创建大量测试输入。
c设置测试床。
d创建随机数据。
e覆盖所有输入组合。
f覆盖等价类的所有代表对偶。
g覆盖逻辑条件的交互。
h通过状态模型创建测试场景。
130)将测试生成与测试执行分开。例如:数据驱动的自动化测试。这种分离的优点:测试易于理解和评审;可使用不同的测试工具或程序设计环境生成和执行测试;如果预先生成数据,则更容易重复测试;不同的测试专业人员会各自关注自动化测试的不同方面。
131)使用标准脚本语言。例如:Perl、JavaScript、Python。测试员可使用它生成测试用例、访问编程接口、检验结果。注意:脚本语言是便于使用而不是用于提高执行性能的高级语言。建议避免使用提供商自己专用的脚本语言。
--132)利用编程接口自动化测试。公共API(指可用来实现测试的编程接口)和私用API(指没提供编程接口软件可能有不公开的接口)因更可能提供稳定性和利于检测和隔离,所以想要搞好测试自动化,就须学习或找了解这些编程接口的人帮忙。
133)鼓励开发单元测试包。测试员需一个像Junit这样的框架来管理测试包的执行,代码通过该语言所支持的一般调用接口测试。将单元测试用于回归测试、冒烟测试和配置测试。
134)小心使用不理解测试的自动化测试设计人员。注意:我们应该运用评审、设计策略和测试来防止开发设计的自动化程序错误。
135)避免使用不尊重测试的自动化测试设计人员。
136)可测试性往往是比自动化测试更好的投资。例如:安装软件后,用户需检查记录文件以查看是否安装有误。如何自动化这种测试?更好的思路是把这些作为软件的一个功能在产品内部实现。这样也许更可靠,实际上可直接使用户受益。还有一个例子:断言是代码中语句,如果结果为假则指示出现错误。断言放入被测软件,以检查结果是否合理,与编写外部代码检验结果相比,这种方法往往更容易、更高效。
137)可测试性是可视性和控制。可测试性如:访问源代码、日志、诊断、错误模拟、测试点、事件触发器、读入老的数据格式、测试接口、定制控件支持、允许多实例(即允许同一台计算机上运行多个客户端或代理)。
138)尽早启动测试自动化。原因:
a当测试已成型后,很难把资源转向自动化。
b当测试员和过程都集中于手工测试后,他们会抵触变更。
c设计完成后,程序员在可测试性要求方面会变得不那么合作。
注意:不要一开始就尝试自动化所有东西,迟早建立基础设施,但在选择要自动化哪些测试时要慎重。
139)为集中式测试自动化小组明确章程。注意:如果有这样的小组,要确保有明确的章程描述要提供的测试辅助类别;应如何提出请求;以及如何平衡相互矛盾的要求。建议要求接受帮助的测试小组指定专人参加测试自动化项目,优点:
a可以评估他们做出的承诺或所面临的实际问题。
b通过培训其员工,可减少后续维护和失效分析要求。
c通过与该测试小组合作,可以从头至尾在项目中把他们的测试需求结合到工作中。
140)测试自动化要立即见效。应把关注点放在影响大、成本小的自动化任务。如下是可供参考的自动化切入点:
a系统设置与准备。
b辅助诊断:数据破坏和内存泄漏缺陷一般到该数据被访问或内存耗尽才会被检测出来,而构建这种检查内存工具也不困难。
c会话记录:严谨的错误报告要示提供完整的配置信息,程序可自动收集和报告必要的信息。
d测试生成:利用自动化手段生成测试输入。
141)测试员拥有的测试工具会比所意识到的多。因为有些测试工具并没贴上“测试工具”的标签。例如:内存监视器、宏工具等。