终极反馈环:从客户上报的缺陷中学习

发表于:2017-7-27 11:01

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Emanuil Slavov    来源:InfoQ

  意外惊喜
  有三件事是我们这一过程没有预料到的,它们带给我们一些意外惊喜。
  首先是,所有客户上报的缺陷中,有38%最终回归了。这意味着本来一个功能可以正常工作,我们修改了部分代码(为了修复问题或增加功能),随后用户上报称原本正常的功能无法使用了。我们并未在内部发现这样的问题。但我们知道,自己也进行了回归测试,可结论中的数据并没有那么高。这意味着我们并不具备任何类型的自动化测试可以充当检测机制,并告诉我们“你刚刚增加的那段代码可以正常工作,但会破坏某个原有功能,发布前一定要检查并修复”。通过编写自动化测试,即可将位于两个不同位置的功能逻辑“粘合”在一起。但这是一柄双刃剑。可以帮助我们更高效地捕捉回归,但同时也可能拖累前进的脚步。提交之后出现太多失败的测试会降低我们的速度,因为在继续之前还需要修复这些问题。这一过程需要权衡,但对我们而言,钟摆已经摆动到距离我们希望实现的快速开发太远的高度,因此我们需要扭转自己的方向。
  第二个惊喜是: 自动化测试金字塔指南 并不能帮助我们提早发现更多缺陷。客户上报的缺陷中,仅有13%可以通过编写单元测试提早发现,而与之对应的,API层面的测试可提早发现其中的36%,UI层面的测试可发现21%。菱形(大部分测试都在API层面上进行)比金字塔形更适合我们。这一问题源自我们软件的本质特征。我们的软件是SaaS应用,主要功能是通过互联网收集大量数据,并将其保存在不同数据库中以供后续分析。大部分缺陷位于不同软件的“缝隙”中。我们有超过19种不同服务,这些服务均需要不断进行网络通信。这些服务的代码位于不同代码库中,因此仅使用单元测试无法获得足够好的效果(我们考虑只在内存中运行单元测试,不涉及网络和数据库文件系统,如果有必要还会将测试数量翻倍)。同时我们认为,随着微服务和Lambda函数的崛起,相比简单的单元测试,针对完整部署的应用进行高层面的集成式测试可以更有效地发现缺陷。大部分缺陷位于不同服务地边界之间,只有针对完整部署的应用程序进行测试才能发现。在隔离的环境中(使用单元测试)对代码片段进行测试,是无法发现这些缺陷的。
  单元测试依然很有用,但并不需要对所有代码执行此类测试。我们发现只对循环复杂度(Cyclomatic complexity)不低于3的方法(72%的缺陷位于此类方法中)以及规模超过10行代码的方法(82%的缺陷位于此类方法中)进行单元测试就够了。
  第三个惊喜是:无论在内部进行何种类型的测试,都无法完全发现所有缺陷。始终有30%的缺陷只能由客户发现。为什么?边缘案例、生产环境的配置问题、非预期使用模式、不完整或错误的规范。如果有足够的时间、资金和资源,我们也可以发现那30%的缺陷,但对我们来说这样做在经济上不可行。我们面临激烈的市场竞争,需要快速前进。与其永远等待着发现那飘渺的30%,不如任其存在,但 我们会尽可能通过优化提前发现它们并快速修复 。当客户上报了此类缺陷并完成调查,我们会从中学习经验并进一步完善我们的系统。
  举措
  我们针对开发者和测试人员的流程进行了四个改动:
  每个功能至少写一个自动化测试。如果可能,尽量专注于API测试,因为这样有助于找出更多缺陷。
  就算最小规模的修复,也要手工进行健全性检查和直观验证。
  要求团队领导进行代码审查。除非审查通过,否则代码不允许推送至生产环境。
  测试过程尽可能使用边界值:过多数据、过少数据、年初和年底等,8%的缺陷都是此类值引起的。
  此外在技术方面也有四个改动:
  1) 每天早晨审查生产环境过去24小时的日志,在其中查找错误和异常。如果发现问题,则以高优先级修复。这样就可以尽可能早发现问题,有时客户打电话告知我们遇到问题,我们已经开始着手修复了。
  2) 我们有长时间运行的API集成测试,以前通常需要运行三小时。通过必要的改进(主要改进为:专用测试环境、测试数据生成、模拟外部服务、并行运行),相同测试现在可在三分钟内完成。我们曾受邀在2016年Google Test Automation Conference上介绍了自己的做法: 渴望速度 – 将自动化测试从3小时提速至3分钟 。这让我们的缺陷查找过程实现了飞跃,因为可以在每次提交后自动运行所有测试(静态代码分析、单元测试、API测试)。现在我们已经不需要每晚进行测试,也不再需要冒烟测试(Smoke test)。如果所有检查均成功通过,就可以非常自信地立即发布到生产环境。
  3) 生产环境中的缺陷有时候会造成异常,而这些异常会在应用程序的日志文件中留下线索。调查过程中,我们发现相同的异常甚至早在发布到生产环境之前,就已经出现在测试环境的日志文件中了。这样来看,其实我们在真正发布到生产环境前,就有机会发现这些缺陷,但前提是对测试环境的日志进行监视。因此我们对自动化测试的执行进行了一些改动,就算所有自动化API测试均已成功通过,我们依然会在每次测试完成后检查日志文件中是否存在错误和异常。有时候因为糟糕的编码实践(例如只是记录异常信息但不进一步扩大),成功通过的测试也有可能导致内部异常但无法主动体现出来(例如主动让测试失败)。此时我们会让构建失败并调查遇到的异常。
  4) 约有10%的缺陷是由未能妥善处理的非预期数据造成的:特殊字符或Unicode字符、二进制数据、出错的镜像。我们开始收集此类数据,并在自动化测试需要创建测试数据时,会使用这些内容作为“异常”数据。
  收效
  下图展示了我们所有举措的收效,每个柱状条对应一个季度。请留意最后四个季度,客户上报的缺陷数量持续下降。上个季度我们的缺陷数量是自从两年半前开始收集此类信息以来最少的。最后一个季度和缺陷数量最多季度之间的降幅超过了四倍。
  另外还有一件事需要注意。通常,产品的代码行数(LoC)越大,包含的缺陷就越多,但缺陷数量和代码行数之间的比例是固定不变的。在我们的情况中,虽然代码行数不断增加,但最后四个季度的缺陷数量在不断降低。
  如何着手
  调查客户上报缺陷,确定问题根源,通过修复解决问题,收集相关信息,整个过程对大部分人而言都极为冗烦。我的建议是:为缺陷调查预留专门的时间(例如每天一小时)。一旦克服了最初的不适应之后,假设你打算调查过去某天发现的缺陷,数据的收集过程将更加完善,自动化程度也会更高。然而尽管如此,我的精力依然不足以支撑每天八小时的缺陷调查。
  确保可以将客户上报的缺陷与内部发现的缺陷区分对待。在开发修复程序时,请将缺陷的ID放在提交信息中,这样即可一一对应。
  尽可能及时地调查缺陷 — 等的越久,需要花费的时间就越多,毕竟人的记忆很快会衰退。
  让团队之外的某人负责调查缺陷。这个人不应与代码有任何感情联系,否则很有可能做出不够客观的判断。
  如果要追踪太多指标,你很快会被淹没其中,因此需要明确哪些指标对组织而言是有用的,是可行的。
  收集所有此类信息似乎需要大量工作(确实如此),但我敢保证你的每秒钟投入都是值得的。这一过程还为你提供了巨大的学习机会。
  结论
  调查客户上报缺陷的根源能为组织带来巨大价值。最开始的数据收集工作很不容易,但其中蕴含了大量学习的机会。让人吃惊的是有很多公司目前并没有这样做。目前的大部分组织都在争夺同一批人才,或者可以使用相同的硬件资源(AWS),你又该如何脱颖而出?为了维持客户满意度,降低成本,提高员工参与积极性,最佳的办法是“内视”,毕竟你已经有数据了。最终,所有举措都是为了实现持续不断的改进。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号