在InfoQ看到一个google关于test的演讲, 非常精彩
作者演讲中提到的众多方法和实践, 其实也正是我们每天工作中遇上的。 当然我还在摸索中, 没想到这个30分钟的演讲能够把很多方面都完美归纳整理, 它的价值在我看来等同于元素周期表之于化学的贡献。
讲座中包含了两个对我来说比较新的东西。
第一个是"开发测试"。 作者没有深入, 每次提到开发测试都是简单带过, 只说了这个是和单元测试独立的, 需要开发人员执行的测试。 传统方法中, 开发人员的压力更多来自于进度。 所以推动开发人员对代码质量的热情, 和终集成后产品质量的热情是非常重要的一个环节。 开发测试是实现这个目的的一个很重要的工具, 但是难点在于如何定义和执行。 是让开发人员手动过一遍预先设计的任务, 让开发人员设计并且执行一套自动化? 还是简单地分担部分测试人员的工作? 我个人认为, 开发测试的文化重于流程和结果。 而文化不是简单堆砌一些流程, 表格, 文档可以搞定的。 希望作者能够跟深入介绍下如何在开发团队中推动这样的文化。
第二个是diff sign off。 这个问题的背景在执行大的sign off流程中, 是需要把所有的回归测试 (我们也叫full test pass)都跑一次呢, 还是有什么简单些的办法。 作者这里提到了diff sign off。 是说重要的回归测试固然要跑, 但是我们可以根据产品的变化, 特别是代码的变化, 来舍弃一些回归测试。 比如前一个milestone跑过了性能测试的回归, 在接下来的一个月中, 所有的修改都是针对localization比如汉化, 而且通过代码比较工具分析下来的确也是这样的话, 那测试人员不需要跑所有的性能回归测试了。 在我们的测试过程中, 我们没有对应的专用名字, 但是在某些时候还是用了同样的方法进行分析。 我个人认为这是一种非常高效,值得推广的方法, 但实际情况是没有人明目张胆地提出来这样操作。 我觉得主要因为我们组织不够agile, 跳票习惯了, 所以多花点时间来个全回归终归安全一点。 次要原因是自动化覆盖的确比较全面,(当然不同team的质量有高低), 所以好像也没有太大必要。 在google 10个开发里面只有1个测试, 比我们现在还极端, 所以diff sign off自然很有用武之地。
关于diff sign off, 我上个星期的类似的例子是, 我们把工具升级到vs2010了。 但是前面一个milestone发布的东西是vs2008的。 大家讨论要不要留一个vs2008的环境, 谨防要出hotfix。 我的意思是要出hotfix也用vs2010编译是了阿。 但老板的意思是, 如果这样的话, 那发布hotfix光冒烟不够, 一定要全回归, 因为编译器变了。 我在想, C#写的标准代码, 编译器导致问题的几率是非常低的。 我觉得编译器的安全程度反而大于冒烟的安全程度。 所以, diff sign off的推动, 很大程度上取决于既存的流程和经验。
另外, 讲座中也包含了一些我认为应该包含却没有包含的东西。
作者强调了测试角色的历史变化, 提到了新时期测试工作的目标。 但全篇所讨论的测试, 更多偏向于after the fact这个现实。 里面强调单元测试, 开发测试等需要开发人员注意的东西, 但这一切都是发生在编码之后。 我认为agile test, 以及整个软件测试应该关注如何把bug扼杀在编码之前。 BJ一般把这个叫做"fix the bug before the fact"。
这个要展开讲很多了。 我个人实践下来有效的方法有几个。
第一个是要让测试人员及早参与, 至少不能晚于开发人员。 当有了"fix the bug before the fact"的意识的时候, 无论测试人员多么早参与都是有事情可以做的。
第二是要做"psychical test" (我根据psychical debug发明的词, 可反以为思维测试)。 通俗一点, 是要从一开始对spec和design进行测试, 而不是等到代码出来后。 让测试人员及早参与是实现这一点的基础。 比如当详细需求出来后, 仔细阅读需求文档, 根据我的经验, 往往能找到很多互相冲突矛盾的地方。 当设计文档出来后, 思维测试更为重要, 而其中的关键是要抓住细节。 我发现大多数团队在做spec review的时候, 都不会太深入细节。 一个设计, 整体看起来没问题, 模块分工没问题, 那基本上算过了。 所谓深入细节, 是要求把所有能想到的可能性, 案例, 数据流动, 性能, 可扩展性等等, 无论优先级高低, 都尽可能地拿到这个设计中用思维走一次。 有问题的地方立刻写下来和开发人员确认清楚。 如果思维测试走过去比较困难, 可以立刻写一个prototype来证明。 相比代码出来后, 在这一个阶段消灭掉bug只需要1/10不到的开销。 所以千万不要浪费spec/design review的时间。
第三是深入代码实现。 通俗点说, 是要test做到和dev一样熟悉产品代码。 我承认这一点有很有争议性, 可能更多的只能代表我的个人习惯。 深入代码实现不同于白盒测试。 深入代码的目的, 在于了解具体实现所付出的风险, 以此作为依据安排测试。 比如抓取关键字的功能来说, 使用正则和使用自己的parser都可以做到。 如果使用了前者, 那对性能方面往往需要测试的更多关注。
另外, 我认为作者对于UI自动化的认识有些极端。 作者觉得UI自动化不应该超过20%。 UI自动化不稳定, 前端的UI变化导致UI自动化维护成本很高。 我虽然说只做了3年的测试, 但其实测的都是UI, 而且是WinForm和WPF, 不是HTML。 作者提到的原因都是正确的, 我深有体会, 但并不等于说没有解决办法。
首先, UI自动化已经有相当成熟和稳定的Windows API了。 相比几年前通过Windows Message和屏幕位置的实现来说, 现在通过UIA来实现UI自动化非常稳定, 而且都是C#的实现。 项目中我们可以使用录制工具, 但是我们发现其实直接写代码来的效率更高, 只是偶尔借助工具自动生成代码。 UI自动化的性能, 稳定性, 主要还是取决于实现的质量。 实现的开销, 其实现在和API Automation相比, 我认为UI多多20%而已。 如果是测试HTML的UI, 那更加简单和稳定了。
其次, UI自动化的维护其实是取决于测试代码的质量。 当UI发生变化的时候, 我相信都是渐进的。 只要UI自动化代码设计合理, 这种渐进的维护其实很容易。 举个例子, 假设login。html发生变化了, 理想的情况是之需要更新自动化代码的资源文件。 如果逻辑也要变化, 那可能需要修改login UI proxy的代码, 但是接口是稳定的。 再不行, 那login这一步现不走UI了, 简单修改config替换成非UI的provider实现走http post好了。 所以, UI自动化并不难, 开销并不大。
UI自动化提供的价值并不能被其它自动化替代。 因为UI才是客户真实使用的。 而且很多简单的UI操作其实可以覆盖底层多个API, 完全是简单实现达到大覆盖率。 和API自动化更不同的是, 很多bug只在UI自动化下面才容易暴露出来, 这主要是UI操作对timing非常敏感。 在我做的几个UI相关的产品中, 几乎都出现了当主界面刚出现, 立刻操作导致崩溃的问题, 而且这样的问题都是UI自动测试中暴露出来的。
所以对UI自动化, 不应该简单地边缘化, 而是找到正确的解决方法。