写点什么

自动化测试——敏捷测试的基石

2010 年 12 月 27 日

在专栏的上一篇文章《什么是敏捷测试》中,我们介绍了敏捷测试的主要特点。作为被冠以“敏捷”名称的测试,敏捷测试同样以“快”为目标。在敏捷测试中,“快”有三个方面的含义:

  1. 团队能够通过测试快速获知系统当前所处的状态,了解距离可工作的软件还有多远;
  2. 能够在一个迭代周期中快速完成回归测试和对新功能的测试;
  3. 开发工程师能够从持续的测试中得到快速的关于提交代码反馈。

简而言之,敏捷测试要求测试能够测试在“短的时间间隔内持续发生”且能够在“短时间内完成”。考虑到纯粹的依赖人工测试基本不可能达到“短的时间间隔内持续发生”和“短时间内完成”这两个目标,而自动化测试在执行效率方面具有天然的优势,在敏捷测试中使用自动化测试技术应该是自然而然的选择。

考察敏捷开发中的一个迭代周期:

  1. 在迭代周期开始的时候,团队与客户一起定义本迭代周期内需要完成的功能;
  2. 团队建立验收测试验证标准;
  3. 开发工程师开始实现新功能,使用 TDD 为产品建立安全网,使用持续集成尽可能保证每一次代码提交不引入新的缺陷;
  4. 所有新功能被添加后,在 RC 上运行回归测试保证原有功能的正确性;针对新功能运行测试保证新功能的正确性;
  5. 执行验收测试验证系统是否达到可交付的标准。

除 1 和 2 外,剩下的 3 个项目都与测试执行密切相关,如果依靠手工测试来进行这些项目,毫无疑问,测试会成为整个敏捷开发的瓶颈。而如果把这些项目中的测试建立在合适的自动化测试基础上的话,测试就可以和开发一起敏捷起来。从这个角度来说,把自动化测试描述成“敏捷测试的基石”毫不夸张。

自动化测试并不是新鲜事物。从 80 年代起,对软件自动化测试的研究就从来没有停止过,而自动化测试工具也一直是测试工程师津津乐道的话题。IBM、HP、Borland 等许多提供软件开发解决方案的公司都拥有完整的测试解决方案;在开源社区,自动化测试工具的种类也不下于 100 多种。这么说起来,是不是只要选择了合适的工具在测试中进行部署,就能快速的建立起敏捷测试需要的自动化测试基础了呢?根据美国某组织在 2005 年开展的一项非正式的调查,在所有参与被调查的 200 多个自动化测试项目中,完全成功的只有 30 多个,不到 20%;完全失败的却达到 100 多个,占到了 50% 的比例。

自动化测试项目为什么会失败?根据调查,“不合适的自动化测试目标”与“从自动化测试中无法获得收益”是项目失败的主要原因。希望把自动化测试定义为“完全替代手工操作”、期望仅仅“在 UI 层建立自动化测试”都不是合适的自动化测试目标;尤其是“在 UI 层建立自动化测试”这个目标一定会带来无法从自动化测试中获得收益的后果。

UI 自动化测试是自动化测试领域中较早被研究的,其主要出发点是使用工具和脚本驱动应用操作,依靠工具对 UI 层的元素属性进行验证。现有的大部分商业测试工具,如 IBM Functional Tester、HP QTP 等都属于这一类工具。从好的方面来说,UI 自动化测试相对其他自动化测试更接近真实用户;但不得不说的是,UI 自动化测试的高昂的投入往往是组织不能持续进行自动化测试原因。

我参与第一个自动化测试项目的时间是在 12 年前。在那些惨痛的日子里,我会痛苦地看着我苦心建立的自动化测试脚本以高达 50% 的失败率运行,然后再花上 2 个星期更痛苦的调试和修复自动化测试脚本的时间。随着脚本数量的增加,我的痛苦如日俱增。最后,我不得不放弃了对这些昂贵的自动化测试脚本的维护,转向我情感上不情愿,理智上却不得不做的选择:重回手工测试。

12 年前的例子并不是我唯一经历的 UI 自动化测试的痛苦,实际上,在 10 多年的软件测试生涯中,这样的不愉快各种情况下一再重复。下表是前年我们的某个完全依赖于 UI 自动化测试项目中的自动化测试投入产出比较表。

自动化测试覆盖率

功能点数量

测试用例数量

(自动化 / 全部)

自动化测试执行

失败率(平均)

每个测试周期的

人员投入

0%

65

0/182

-

2**** 人周

20%

83

41/210

10%

1.5 人周

44%

110

131/302

22%

2 人周

61%

120

213/350

43%

3.5 人周

UI 自动化测试带来痛苦的主要根源在于 UI 本身的不稳定性。由于 UI 是应用与用户的直接交互界面,用户的大量需求都直接对应在 UI 本身的改变上,这就导致了 UI 本身的不稳定,建立在 UI 上的自动化测试也因此不稳定。当然,除了不稳定外,UI 自动化测试带来的测试环境的需求也是导致 UI 自动化测试开销剧增的原因之一;另外,UI 自动化测试本身并不能很好的帮助定位缺陷,对开发工程师而言,其在反馈上的价值远不如单元测试。

除了 UI 自动化测试外,在敏捷测试中其他可用的自动化测试还包括单元测试与接口测试(或者叫服务测试)。下图是敏捷开发中被广泛认可的自动化测试产出金字塔,在相同投入的情况下,单元或是代码级测试能带来最大的收益,而 UI 层面的收益最小。

自动化测试所涉及的技术非常多,例如在单元测试中经常需要使用到的 Mock 技术,基于针对不同语言而不同的解依赖技术等;在接口测试层面,更是需要根据接口本身的类型和特点确定具体的测试技术;在 UI 层,根据应用的不同(桌面应用,Web 应用,嵌入式应用等),自动化测试技术也存在巨大的差异。

关于各种自动化测试技术的讨论,本文在后续文章中会选择其中的一些进行重点介绍,本文则主要介绍 Diff 技术这种与传统的“比较预期输出与实际输出”略有不同的自动化测试技术。

Diff 技术,顾名思义,其主要关心的是“不同”。以搜索引擎产品的测试为例:以同一个关键字在搜索引擎上进行多次重复测试(查询),随着时间段的变化,搜索引擎的索引数据也在发生变化,即使对同一个关键字,也不太可能在每次测试时给出一个所谓的“预期结果”。

怎样才能在这种情况下开展测试?一种可行的技术是就是“Diff”技术。下图展示了 Diff 方法的应用。

简单来说,Diff 方法的应用包括以下步骤:

  1. 设置两个待比较的版本实例(通常是相邻的两个版本,例如 RC 和上一个产品版本),两个版本具有相同的数据基础或后端环境;
  2. 使用发送模块同时向两个版本发送相同请求;
  3. 比较模块收集两个实例的输出并对其进行比较;
  4. 比较结果输出为 Diff 报告。

Diff 报告体现的是两个实例之间的不同,不同并非一定是由于缺陷导致,因此 Diff 报告需要通过人工审阅,判断报告中“不一致”的原因,决定后续步骤——后续步骤通常包括创建一个缺陷,安排探索性测试,或是据此确定回归测试范围等。

Diff 测试技术可以在多个测试层面上被应用。例如,在 UI 层面上,可以通过图片 Diff 的方式(比较两个版本在相同输入情况下的 UI 截图)发现应用界面上的变化;对 Web 应用来说,也可以以文本 Diff 的方法比较两个实例输出的 HTML 文档,或是特定页面元素;在接口层面上,可以比较在两个实例上,相同的 UI 操作导致的前后端通讯的不同……

Diff 技术甚至可以在测试过程中帮助确定测试范围。例如,对一个 RC 的全面的 Diff 发现,所有 100 个功能点中,有 80 个功能点的 Diff 结果与上一个版本没有任何差异,有 20 个功能点的 Diff 结果与上一个版本存在差异。基于这个结果,我们可以很容易的将存在差异的 20 个功能点作为 RC 测试的重点——个人认为,与依靠代码分析确定测试范围相比,这种方式直观有效得多。

当然,在实际项目中应用 Diff 技术也会遇到很多挑战,如何尽量消除 Diff 结果中的“噪声”是一个关键问题。以应用基于图片的 Diff 技术为例,如何消除图片比较结果中的噪声就是一个既需要技术手段(通过图片比较算法)也需要非技术手段(建立针对每个页面的 mask)的话题。

关于作者

段念:Google 中国高级测试经理,毕业于华中科技大学,先后在通讯、嵌入式软件、互联网等多个行业的国内外知名公司中从事软件开发与测试工作。对软件测试中的技术和管理工作有独到见解,对软件测试团队管理、自动化测试、性能测试与开发测试有较多研究。


感谢张凯峰的策划以及审校。

2010 年 12 月 27 日 00:266054

评论

发布
暂无评论
发现更多内容

巩固知识体系!应聘高级Android工程师历程感言,面试建议

欢喜学安卓

android 程序员 面试 移动开发

数据加密:你应该知道的数仓安全

华为云开发者社区

数据加密 GaussDB(DWS) 数仓安全 透明加密 加密函数

上线几小时下载量破百万!无价的这份阿里并发编程图册就这么强势

Crud的程序员

Java 架构 并发编程

小鼎量化机器人系统开发详情介绍

系统开发咨询1357O98O718

【实战问题】-- 缓存穿透之布隆过滤器(1)

秦怀杂货店

缓存 布隆过滤器 java;

如何实现一个简易版的 Spring - 如何实现 Setter 注入

mghio

spring 依赖注入

爱了! Alibaba技术官甩出的“阿里内部Java成长笔记”,差距对比真的是不止一点点

Java成神之路

Java 程序员 架构 面试 编程语言

6面蚂蚁,面试官被窝唬住了,居然开了36K,Java面试怎么就突然简单起来了

Java成神之路

Java 程序员 架构 面试 编程语言

字节跳动5面喜提offer!分享给朋友们面试感受

Java架构之路

Java 程序员 架构 面试 编程语言

SpringBoot-技术专题-启动自动装配过程

李浩宇/Alex

spring springboot

一文归纳Python特征生成方法(全)

泳鱼

Python 机器学习 深度学习

Apache Ranger安全认证配置

大数据技术指南

大数据 3月日更

阿里、字节等大佬神创,必须是全网最全的Netty核心原理手册

周老师

Java 编程 程序员 架构 面试

爱了爱了!阿里大牛亲码Java面试速成指南已助我拿到美团的Offer

Java王路飞

Java 编程 架构 面试 美团

Python OpenCV 图像旋转,取经之旅第 11 天

梦想橡皮擦

3月日更

阿里内产“Redis深度笔记”,从基础深入到源码,不讲一句废话,全是精华!

神奇小汤圆

Java redis 程序员 架构 面试

阿里P7大牛手把手教你!美团Android开发工程师岗位职能要求,附赠课程+题库

欢喜学安卓

android 程序员 面试 移动开发

Github一夜登顶的SpringBoot+vue项目太香了

程序员小毕

Java 程序员 架构 面试 springboot

2021年GitHub上爆火的999页Java面试宝典终开源

比伯

Java 编程 架构 面试 程序人生

牛链NB系统开发案例源码

系统开发咨询1357O98O718

Hashmap的重要变量与高频面试题整理(含答案)

Java王路飞

Java 程序员 架构 面试 hashmap

爽啊,终于又见面了,字节跳动后端社招面试分享

Java架构之路

Java 程序员 架构 面试 编程语言

Spark性能调优-Shuffle调优及故障排除篇

五分钟学大数据

spark Spark调优 3月日更

Mysql之索引选择及优化

程序员小毕

Java MySQL 架构 面试 索引

Ai特征选择,一篇就够了

泳鱼

Python 人工智能 机器学习 深度学习 AI

Android开发必须要会!2021大厂Android面试经验,全网疯传

欢喜学安卓

android 程序员 面试 移动开发

面试大揭秘!从技术面被“虐”到征服CTO,全凭这份强到离谱的pdf

Java成神之路

Java 程序员 架构 面试 编程语言

蚂蚁金服三面Java面试题全解析,这也太难了吧

Java架构之路

Java 程序员 架构 面试 编程语言

WC,误删数据库了,会被开除吗?

Java架构师迁哥

滴滴OCE惊喜福利!

滴滴云

悖论和直觉

架构与源码

自动化测试——敏捷测试的基石-InfoQ