打造零缺陷软件:策略与实践
1. “零缺陷”理念
在软件开发中,应秉持“缺陷是别人的事”这种精英甚至有些“傲慢”的态度。当缺陷出现时,不应习以为常地耸耸肩,而要感到震惊和沮丧,因为缺陷不应被容忍,它是潜在问题待解决的信号。
“零缺陷”本质上是建立一种卓越的文化。一旦发现缺陷,应立即修复,然后思考如何防止此类缺陷再次发生。不过,实现“零缺陷”并非一蹴而就,所提及的实践都需要纪律和严谨性。若人们工作马虎或不在乎工作质量,这些实践就会失效。“零缺陷”文化有助于团队保持所需的纪律,像结对编程、团队编程、团队工作室以及集体代码所有权等方式也有同样的作用。敏捷团队能够且确实可以实现近乎零缺陷,你也可以。
下面是一些常见问题及解答:
|问题|解答|
| ---- | ---- |
|如何预防安全缺陷和其他具有挑战性的缺陷?|威胁建模可帮助提前考虑安全漏洞,“完成完成”清单和编码标准能提醒需解决的问题。但只能预防想到的缺陷,安全、并发等困难领域可能会引入意想不到的缺陷,所以盲点发现也很重要。|
|应如何跟踪缺陷?|若团队产生的新缺陷不多,可能不需要缺陷数据库或问题跟踪器。若缺陷太大无法立即修复,可将其转化为一个故事,并像处理其他需求细节一样跟踪其详情。|
|在将缺陷转化为故事之前,应花多长时间处理它?|这取决于可用的空闲时间。在迭代早期空闲时间较多时,可能花半天处理一个缺陷;后期空闲时间较少时,可能只花10分钟。|
|有大量遗留代码,如何在不抓狂的情况下采用“零缺陷”政策?|这需要时间。先浏览缺陷数据库,确定当前版本要修复的缺陷,每周至少安排修复一个,且倾向于尽早修复。|
每1 - 2周,随机选择一个最近的缺陷进行事件分析,至少进行非正式分析,这有助于逐步改进开发系统,预防未来的缺陷。
实现“零缺陷”理想依赖大量敏捷实践,在团队熟练掌握这些实践之前,别期望缺陷数量会大幅减少。反之,若使用了聚焦和交付实践,但每月仍有较多新缺陷,可能意味着方法存在问题。通常在几个月内应该能看到缺陷率的改善,若未看到,可查看故障排除指南。
当团队拥有“零缺陷”文化时,会有以下表现:
- 团队对软件质量充满信心。
- 无需手动测试阶段就可放心将软件发布到生产环境。
- 利益相关者、客户和用户很少遇到不愉快的意外。
- 团队将时间用于生产优秀的软件,而非忙于救火。
还可以通过以下方式进行实验:观察流程中在末尾检查质量的部分,思考如何从一开始就构建质量。也可以使用更多、更高质量的测试来发现和修复更多缺陷,但这不如从一开始就构建质量有效,还会减慢开发速度,使发布更困难。一些公司设立单独的QA团队来提高质量,但这可能会降低质量,因为开发团队自身对质量的投入会减少。
2. 盲点发现
即使是熟练的交付团队也难免存在盲点,盲点发现就是找到这些思维差距的方法。要找到盲点,需审视团队的假设,考虑团队成员面临的压力和约束,想象团队可能面临的风险以及成员可能错误认为正确的事情,提出可能出现的盲点假设并进行调查验证。测试人员通常在这方面特别擅长。
当发现盲点时,不仅要解决发现的问题,还要修复差距。思考开发方法是如何导致缺陷出现的,然后改变方法以防止此类缺陷再次发生。
以下是几种具体的盲点发现方法:
2.1 验证式学习
人们通常认为的缺陷是逻辑错误、UI错误或生产故障,但最常见的盲点更基础、更微妙,即团队构建了错误的东西,缺乏产品 - 市场契合度。很多团队认为自己的工作只是按照要求构建产品,像一个软件工厂。实际上,没人真正知道应该构建什么,团队的工作是测试这些想法,学习真正应该构建的东西。
敏捷团队的基本活动是将想法转化为产品,观察客户和用户的反应,然后决定是调整方向还是坚持下去,这就是验证式学习。很多团队在软件发布时才首次测试想法,这风险很大。可使用Ries的构建 - 测量 - 学习循环:
1.
构建
:查看团队的目标和计划,确定关于产品、客户和用户的核心假设,选择一个进行测试,思考“能展示给真实客户和用户的最小东西是什么”,可以是模拟产品或纸质原型,且不一定要涉及所有用户,但要涉及实际会购买或使用产品的人。
2.
测量
:在向人们展示所构建的东西之前,确定需要看到哪些数据才能证明或反驳假设。数据可以是主观的,但测量应该是客观的,例如“70%的客户表示喜欢我们”就是对主观数据的客观测量。
3.
学习
:测量结果会验证或反驳假设。若验证了假设,继续测试下一个;若反驳了假设,则相应地改变计划。
例如,一个团队的目标是改善脊柱手术护理结果,计划构建一个工具为临床负责人提供手术数据的各种视图。其核心假设之一是临床负责人会信任该工具呈现的基础数据,但数据可能质量不佳,负责人往往持怀疑态度。为测试该假设,团队决定:(构建)使用七个诊所的真实数据创建工具的模拟版本;(测量)将其展示给这七个诊所的负责人;(学习)若至少五个负责人认为数据质量可接受,假设将得到验证,否则团队将制定新计划。
验证式学习是优化团队的标志之一。根据组织结构,可能无法充分利用它,但基本理念是适用的,不要仅仅假设交付故事就能让人们满意,要尽可能检查假设并获取反馈。
graph LR
A[构建] --> B[测量]
B --> C[学习]
C -->|验证假设| A
C -->|反驳假设| D[改变计划]
2.2 探索性测试
测试驱动开发能确保程序员的代码按其意图执行,但如果程序员的意图有误呢?例如,程序员可能认为在JavaScript中使用
string.length
来确定字符串长度是正确的,但这可能导致在计算“naïve”这个单词的长度时出现错误。
探索性测试是发现这些盲点的技术,它是一种严谨的测试方法,涉及“利用上一次实验的结果,快速连续地设计和执行微小实验”,步骤如下:
1.
制定章程
:决定要探索的内容及原因,如团队最近采用的新技术、新发布的用户界面或关键的安全基础设施等。章程应足够宽泛,能提供1 - 2小时的工作内容,又要足够具体以帮助聚焦。
2.
观察
:使用软件,通常通过用户界面,也可使用工具探索API和网络流量,观察系统的隐藏部分,如日志和数据库。寻找两件事:异常情况和可修改的内容,如URL、表单字段或文件上传,这些可能导致意外行为。过程中要做好笔记,以便必要时能追溯步骤。
3.
改变
:不要正常使用软件,要突破其边界。例如在文本字段中输入表情符号、输入零或负数的大小、上传零字节文件、损坏的文件或会扩展到数TB数据的“爆炸”ZIP文件、编辑URL、修改网络流量、人为减慢网络速度或向无可用空间的文件系统写入数据等。根据观察和对系统的理解决定下一步探索内容,也可查看代码和生产日志来补充见解。若探索安全功能,可使用团队的威胁模型作为灵感来源或创建自己的模型。
2.3 混沌工程
在大型网络系统中,故障是常见的,代码必须具备对这些故障的弹性,而错误处理往往是经验不足的程序员和团队的常见盲点,即使经验丰富的团队也无法预测复杂系统的每一种故障模式。
混沌工程可以看作是一种专注于系统架构的特殊探索性测试,它通过故意向运行中的系统(通常是实时生产系统)注入故障,来了解系统对故障的响应。虽然这看似有风险,但可以进行可控操作,它能让你识别出仅因复杂交互而出现的问题。
混沌工程与探索性测试类似,都要寻找改变正常行为的机会,但它关注的是意外的系统行为,如节点崩溃、高延迟网络链接、异常响应等。其核心是通过实验来确定软件系统是否如你所想的那样具有弹性,具体步骤如下:
1.
了解系统稳态
:明确系统正常运行时的状态,了解团队或组织对系统弹性的假设,确定首先要验证哪个假设最有价值,以及在进行实验时如何判断实验的成败。
2.
准备改变系统
:例如移除一个节点、引入延迟、改变网络流量、人为增加需求等(如果是首次测试,从小规模开始,以限制失败的影响)。形成一个关于会发生什么的假设,并制定在情况恶化时中止实验的计划。
3.
实施改变并观察结果
:判断假设是否正确,系统是否仍能正常运行。若不能,则识别出了一个盲点。无论结果如何,都要与团队讨论结果,完善对系统的共同认知,并根据所学决定下一个实验。
很多关于混沌工程的案例都涉及自动化工具,如Netflix的Chaos Monkey。但在团队中应用混沌工程时,不要过于关注构建工具,进行广泛的实验比自动重复单一实验更有价值。虽然需要一些基本工具来支持工作,且工具会随着时间变得更复杂,但要尽量以最少的工作进行最广泛的实验。
| 对比项 | 探索性测试 | 混沌工程 |
|---|---|---|
| 关注重点 | 意外的用户输入和API调用 | 意外的系统行为 |
| 实验场景 | 软件使用过程 | 系统运行过程 |
| 核心目的 | 发现软件功能方面的盲点 | 确定系统的弹性 |
graph LR
A[了解系统稳态] --> B[准备改变系统]
B --> C[实施改变并观察结果]
C -->|成功| D[继续实验]
C -->|失败| E[识别盲点并改进]
2.4 渗透测试和漏洞评估
虽然探索性测试能发现一些与安全相关的盲点,但对安全敏感的软件需要专家进行测试。
渗透测试(Pentesting)是指让专业人员像真正的攻击者一样尝试攻破系统的安全防线,它不仅涉及对团队编写的软件进行探测,还会从更全面的角度考虑安全问题,包括生产基础设施、部署管道、人为判断甚至物理安全(如门锁)。渗透测试需要专业知识,通常需要聘请外部公司,费用较高,结果很大程度上取决于测试人员的技能。因此,聘请渗透测试公司时要格外谨慎,要知道执行测试的人员至少和选择的公司一样重要。
漏洞评估是渗透测试的一种低成本替代方案。虽然渗透测试从技术上讲也是一种漏洞评估,但大多数宣传“漏洞评估”的公司进行的是自动化扫描。
一些漏洞评估会对代码和依赖项进行静态分析,如果速度足够快,可以将其纳入持续集成构建中(如果不行,可以使用多阶段集成)。随着时间推移,评估供应商会在工具中添加更多扫描功能,以提醒团队新的潜在漏洞。其他评估会对实时系统进行探测,例如供应商可能会探测服务器是否有暴露的管理界面、默认密码和易受攻击的URL等,通常会定期(如每月)提供一份报告,描述评估发现的问题。
漏洞评估可能会产生大量噪音,通常需要有安全技能的人员对结果进行分类,并找到安全忽略无关发现的方法。例如,一个评估扫描易受攻击的URL,但它不够智能,无法跟随HTTP重定向,每月都会将扫描到的每个URL报告为漏洞,而实际上服务器只是进行了全面重定向。
一般来说,首先使用威胁建模和安全清单(如OWASP Top 10)来指导编程和探索性测试工作,使用自动化漏洞评估来应对其他威胁并发现盲点,最后进行渗透测试以找出遗漏的问题。
综上所述,通过建立“零缺陷”文化和运用多种盲点发现方法,可以有效提高软件质量,使软件系统更加稳定、安全和符合市场需求。在实际开发过程中,应根据具体情况灵活运用这些策略和实践,不断优化开发流程,以实现软件质量的持续提升。
超级会员免费看
1534

被折叠的 条评论
为什么被折叠?



