自动化测试与需求变更
引子
自动化测试是敏捷软件开发的重要实践。在和团队的交流中我常常会听到这样的声音。“自动化测试很好,但是,因为现在需求不稳定,目前还不适合采用这种技术。”
这有可能是对自动化测试在开发过程中作用的误解,使得团队错失改进效能的机会。更重要的是,即便将来有了“需求稳定”的机会来实践,基于这种误解团队可能也难以发挥自动化测试应有的助益作用,并保持长期可持续的改进节奏。
在笔者的开发经验中,无论复杂遗留系统的增强,或是全新探索性产品的开发。自动化测试都为快速高质量的需求迭代提供了有力的保障。想借这篇文章探讨一下二者的关系。
需求变更
首先,我们来看看需求变更这个IT从业者非常熟悉的词。坊间流传的笑话杀死一个程序员只需要改三次需求。那么当我们谈论需求变更的时候我们在说什么呢?
从造成变更的原因来看,有可能有这几种情况:
外界客观条件的变化
比如市场环境的改变,法规、政策的调整。在这个变化日益增多加快的UVCA时代,这种情况的概率确实增加了不少。但从比例来说,团队面临的“需求变更频繁”大多并不是直接由这个层面引起的。
对需求的理解改变
有句话说“需求很少改变,变化的是我们对需求的理解”。当产品决策人把需求绑定在具体细节的解决方案上,却没有充分挖掘和沟通解决方案背后的需要、价值和假设时。就可能让开发团队感受到在需求决策上朝令夕改,缺乏稳定性。
另一方面,一个充分理解了客户需求,以客户价值为导向的敏捷团队,应该会理解到无论团队还是客户都可能会对需求有更深入的理解。并为此做好准备。
解决方案的改变
就像对于需求的理解会变化,团队在构建过程中也会对可供选择的解决方案有了更深的理解。每次发现了一个更好的改进解决方案的思路,往往也就意味着一次“需求”变更。
发现了信息传递中的误解
从需求到解决方案,到设计思路,再到具体的实现,这个链条的每一步都需要不同角色间的沟通,和对概念的加工、转换、整合。在这个过程中不可避免会出现误解与遗留。当我们发现这种错漏时,往往也会将之称为“需求变更”。这可能也是日常工作中最常碰到的“变更”。
如果秉承一种画地为牢、固步自封的视角,认为开发就是只盯着那个叫做“需求”的文档。但凡有了变化,就是需求变更,就是外界的责任。作为下游的开发只能默默的承担这种“伤害”。
然而从前面分析可以看出:
外界的客观变化并非我们可以控制的,而且一般来说并不会无限制的频繁变化,也很少会毫无征兆的要求立即响应。
对于问题领域和解决方案领域更深认识带来的改变,用后见之明的视角可以归罪为当初没有更好地设计计划。硬币的另一面是,我们总是会在进行过程中学多更好的做法。更好的利用这些改进的机会正是敏捷的秘密所在。
那么为什么实际工作中,会更多地将这些选项看作额外的“变更”而不是改进的“机会”。这可能和最后一种变更的原因有关。
犯错误是人类的天性,对待这倾向,我们可以主动应对建立系统化的方法来不断验证发现错误,并进行矫正,也可以自欺欺人的认为“人人都犯错,但我这次不同”,放任错误累积,反馈滞后,直到最后付出更大的代价。
通过自动化测试,可以帮助团队建立起这样的矫正机制。克服因为担心执行中的错误成本而对改变产生的抵触。进而建立主动抓住改进机会的能力,提高组织应对变化的适应性。
测试
我们提起测试时,往往有不同的侧重点。让我们看看一些常见的隐喻。
考试
某种机制判断被测试对象是否满足一些标准。往往由独立于被测试方的组织进行。往往与被测试方有对抗关系。
在软件开发中,UAT很接近这种隐喻。主要服务于制品的接受方,目的是解答一次构建是否合格。
拟真
比如沙盘进行战术推演。或者像是设计飞机造型时先使用小型模型在风洞中进行验证。这也是一种测试。 软件开发中的原型、迭代产生的中间版本、为了验证假设的MVP、A/B测试等都接近于这种隐喻所表现的测试。主要服务于构建方,目的是较低成本的解答构建者的某种假设是否正确。
探索
在丛林中探险最终找到宝藏,通过重重线索侦破案情,在地层中挖掘考古。这些都是类似这类测试的隐喻。 这种测试接近于软件开发中所说的探索性测试。主要服务于制品的使用方,目的是揭示制品未知的未知。
厘清
就像使用万用表分段定位电路故障。 这类测试服务于构建方,目的是定位问题与具体构造部件的关系。
探针
如同“金丝雀部署”这个名字的来源一样,矿工带着金丝雀来及早发现瓦斯泄漏。 这类测试自动的发现构建过程中偏离正轨的迹象,及早引起构建者的注意。
可能的隐喻还有很多。我们知道并非所有的测试都适合自动化,也并不是所有的测试都对更加高效的构建过程有效。
如果我们建立自动化测试集,却期待它们可以像仿真模拟、探险破案,或是来证明制品会交出满分的答卷,往往会耗费巨大,劳而无功。
为了更好的服务构建过程,应对信息传递中的错误,自动化测试集应该起到的是万用表式的厘清工具或探针式检测的作用。
如何开始
当团队相信建立自动化测试集并不是锦上添花的额外工作,而是更好更快应对变更的前提条件时。如何开始做出改变呢?
放弃“全部或没有的”测试理念
不要期待一下子获得一个满分答卷式的测试集。首先这样成本巨大,而且如前文所说,主要目标是服务于建者而不是验收者。
分析最需要消除的信息传递错误
可以通过分析发布前耗时最多的低效步骤,比如某些手工验证或者回归测试。以及那些每次发布常常遗漏出去,对客户造成影响的缺陷类型,是什么造成了这种遗留? 很多“不小心”的错漏,其实是心照不宣、有意无意的掩盖。掩盖的背后是应该做,却因为成本或复杂度选择不做的事情。 通过自动化测试破除成本的限制,会大大提高构建效率。
投资基础能力,使后续的测试更加容易
自动化一件事总是比单独一次的手工操作需要更多的投入,但这种投入也并非高的不可企及。在解决方案领域基本稳定的情况下,大部分需要克服的困难或者基础的工具代码都可以在其它的测试场景得到重复使用。
第一个自动化测试将会是最需难的一个,选择团队中骨干的技术力量去编写。自动化测试也是软件代码,而且是被团队天天使用的软件。不要把它作为边角料杂务草率的对待,然后又在进展不利时早早的打了退堂鼓。
总结
- 自动化测试并不是和需求频繁变更相互冲突,相反,自动化测试应该帮助团队更好的应对频繁变更
- 建立开发者测试集的主要目的是帮助团队而不是外部评审
- 专注于获得反馈而不是证明100%正确
- 建立测试集需要投资,明智地选择投资策略
变更与测试的相互影响
- 测试了需要的变化
- 测试了意外的改变
- 相关但不关键的改变影响了测试
- 验证方式与细节耦合
- 数据准备
- case 耦合
- 增加测试影响了新增需求的速度
改进的下一步
- 放弃全部或没有的测试观念,分析可能的收益
- 投资建立可复用的测试部件
- 持续回顾现有造成拖累的测试