代码改变世界

探索式测试:测试自动化实例分析

2011-02-01 10:59  liangshi  阅读(2203)  评论(4编辑  收藏  举报

Harry Robinson是微软公司的首席测试工程师(Principle Software Development Engineer in Test),工作于必应(Bing)团队。他在国际会议CAST 2010PNSQC 2010做了两次关于测试自动化的主题报告,都很有启发性。本文从中摘录了若干测试自动化实例。希望通过对它们的分析,能够获得一些可借鉴的经验。

为避免误会,在此重申:本文的素材来自Harry Robinson的主题报告,其内容皆来自他在必应的测试工作。我所做的工作是翻译和评论,并为此过程中的所有错误负责。

案例1:盖特伍德奶奶(Grandma Gatewood)

下面这张截图来自于Harry的一张幻灯片,右侧的老者就是著名的盖特伍德奶奶Grandma Gatewood)。她曾经在67、72、75岁时,三次独自徒步走完阿帕拉契小径Appalachian Trail)。阿帕拉契小径是美国著名的野外徒步路线,穿越14个州,全长3200公里。盖特伍德是首位独自徒步走完阿帕拉契小径的女性,耗时仅三个月。

image

盖特伍德是“超轻徒步先驱 ”(ultra-light hiking pioneer)。维基百科有如下描述:

1955年,67岁的盖特伍德徒步前往阿帕拉契小径,她穿着Keds运动鞋,她把一块军用毛毯、一件雨衣、一块塑料浴帘装在自家缝制的背包里,然后单肩背包徒步,由此她成了超轻背包的先驱。

1970年,时年83岁,她在弗吉尼亚州奥克顿访问阿帕拉契旅行用品商店时,有人询问她对于当时轻量背包装备的看法,她建议:“制作一个雨衣,一个单肩背包,再买双结实的Keds网球鞋。在当地杂货店买好维也纳香肠……其他吃的你可以在路边找到……”

现在,你也许感到疑惑:盖特伍德与测试自动化到底有什么关系?那么,请考虑下面这个问题

如果盖特伍德选择图片左侧男子所用的背包,她能够在67岁之后徒步走遍美国大陆地区所有的州吗?

答案显然是不能。如果选择图片左侧的双肩包,盖特伍德恐怕坚持不了一个星期就要倒下。这是一件显而易见的事情:你所选择的工具不应成为你的负担。然而,我见过一些测试团队,他们使用重量级的流程、框架、基础设施,被自己的选择所拖累,虽然天天抱怨,却不思变更。

盖特伍德的单肩包提示我们自问:

  1. 测试自动化的投入产出比如何?是那些投入最多的测试在创造最多的价值吗?
  2. 我们遵循了“要事第一”(First Thing First)的原则吗?我们的主要精力是投入在最有价值的事情上吗?
  3. 现有的流程、框架、基础设施中,有哪些部分不是必须的?能用更轻量的方法替代吗?

程序员有时在潜意识中认为自己是无所不能的超人,但是我们真的强过盖特伍德吗?她经历过两次世界大战,见证过改变世界的经济危机,养育过11个子女(这是多么强大的管理经验),在67岁时开始新的冒险,获得成功后又迈向新的目标。不要以为超轻背包是一个虚弱老妪的无奈选择,它是一个睿智老者多年人生体验的沉淀。她知道什么是必须的(雨衣、背包、Keds网球鞋、维也纳香肠),什么可以稍后处理、随机应变(“其他吃的你可以在路边找到”)。她知道用超轻背包,她可以走得更远,远得令所有人敬佩。

如果看完本文,你只能记得一点,请不要忘记盖特伍德奶奶的单肩包。

案例2:测试自动建议(AutoSuggest)

image

对于搜索用户,自动建议(AutoSuggest)是一项贴心的设计。但是对于测试工程师,这不是一项容易测试的功能。

  1. 手工探索式测试无法保证测试抽样可以覆盖用户输入。与必应搜索庞大的用户输入相比,手工测试的覆盖率接近于零。传统的等价类划分等测试抽样方法,对于如此海量的、无规则的输入,也无可奈何。
  2. 传统的自动化测试遇到的困难是无法构建测试Oracle。自动建议的核心实现是基于海量数据的人工智能算法。算法的输出受到多个因素的影响,如当前用户的查询、近期的相似查询、自动拼写更正、关键词过滤(如去除色情内容)等。对于特定的输入,很难构造自动建议的“预期结果”。

面对困难,Harry的测试思路是构造启发式测试Oracle(Heuristic Test Oracles)。所谓启发式Oracle,就是使用规则对测试结果进行一致性检查。开始时,Harry的规则非常简单:

自动建议的结果应该以输入字符串为作为缀。

Autosuggestions should have the input string as their prefix.

Harry编写了一个简单的测试程序。它从必应的服务端日志中获得真实用户的查询,调用自动建议的Web Service API,以获得这些查询的自动建议结果,最后利用上述规则对结果进行检查。

很快,测试程序发现了不满足规则的案例。当输入是“nestb”,自动建议返回“bestbuy.com”(百思买,财富500强消费电子零售商)。这是自动建议的拼写更正(Spelling Correction)功能,它将用户的“疑似错误输入”,纠正为一个最可能的结果。该行为是可接受的。于是,Harry将规则修正为:

自动建议的结果应该以输入字符串的合理近似作为前缀。

Autosuggestions should have a reasonable approximation of the input string as their prefix.

虽然不知道Harry的具体做法,我能想到若干“合理近似”的判定方法。

  1. 将单词看作向量,计算向量之间的距离。距离小于指定阈值的单词对,可以认为相互“近似”。
  2. 查询Office Word的拼写更正字典,获得指定单词的所有拼写更正建议。这些建议可以视为单词的“合理近似”。
  3. 调用必应的搜索API,获得搜索结果。搜索结果中的高亮关键词可以视作查询的“合理近似”。

Harry利用修正后的规则又发现了一些违规的案例。如输入“dond”,自动建议返回“nbc.com”。也许这符合某些文化上的约定,但值得进一步调查。再例如,输入“federal trust bank”,自动建议返回“floridalottery.com”。这个建议应该是错误的,需要开发者去调查哪里出了问题。在这个过程中,启发式Oracle更像一个过滤器,它处理海量的数据,过滤出需要测试者人工审查的潜在错误案例。

通过持续运行测试程序,Harry获得了以下成果。

  1. 测试运行了7天,覆盖了2200万个用户查询。
  2. 发现了1万个有问题的建议结果。
  3. 在建议词条数据库中,发现了1.9万个从未被返回的建议词条。它们应该被剔除。

image

当然,真实的测试过程比上述描述要复杂一些。但是,它们都拥有相同的核心:从简单的测试Oracle开始,利用测试反馈持续完善Oracle。Harry将这种迭代式的测试开发过程称作涌现式测试(Emergent Testing)。

案例3:测试行车路线(Driving Direction)

image

在线地图可以给出从地点A到地点B的行车路线(Driving Direction)。那么如何测试该功能呢?

Harry的测试输入集合是全美所有邮政编码(Zip Code)的两两组合。这是一个非常庞大的集合,它提供了令人放心的测试覆盖率。

Harry的测试策略仍旧是构建启发式测试Oracle。开始时,他的规则集合包含这么一条规则:

行车路线的长度与A到B的直线距离没有数量级的差距。

这里需要对在线地图的实现稍作说明。在线地图的实现可以大致分为两层:绘制地图的Web UI和提供地图数据的Web Service API。API能够返回指定邮政编码的经纬度坐标。因此,利用其返回值,就可以算出两点间的直线距离。对于行车路线,API返回的是一系列点的坐标值,Web UI将行车路线路线绘制为贯穿这些点的曲线。计算临近两点间的距离,将结果累加,就可以得到行车路线的长度。因此,上述规则的实现并不复杂。

然而,在实际测试过程中,这条规则却产生了许多“误报”。下图就是一个例子。

image

于是Harry替换了检查规则。新加入的规则是:

从A到B的行车路线的长度与B到A的行车路线的长度没有明显差别。

这条规则没有产生太多的误报,而且发现了一些有趣的错误。下图就是一个例子。

image

对案例2与案例3的再分析

在案例2和案例3中,被测试对象有如下特点:

  1. 难以构造能够给出标准结果的测试Oracle。自动建议的计算是基于海量数据的模式匹配,行车路线的搜索是典型的人工智能算法。在技术上,很难准确预测它们的输出。从业务的角度,这两个问题在现实世界也不存在“标准答案”。
  2. 在这两个应用中,Web UI从Web Service API中获得数据。这意味着,测试程序可以忽略UI,直接调用Web Service API,以测试核心逻辑。良好的设计分层提供了可测试性,而可测试性简化了测试程序的构造。
  3. 测试输入使用真实数据,且相对容易构造。自动建议的测试输入来自必应的服务端日志,测试程序只需要遍历文本日志就可以构造测试输入。行车路线的测试输入是全美邮政编码的两两组合,测试程序只需要读取一个记录全美邮政编码的文本文件,就可以组合出所有的测试输入。
  4. 单个测试执行速度快,这有助于测试程序在较短的时间内完成大量的检查。自动建议的Web Service API的响应时间应该在毫秒级,行车路线的API可以慢一些,但也必须在1~2秒内返回结果。于是,Harry的程序能够检查2200万个输入,能够使用“全组合”策略提供充分的测试信心。

在案例2和案例3中,测试策略有如下特点:

  1. 充分利用计算机的运算能力,将(与人力成本相比非常廉价)机器资源使用到极致。
  2. 用简单的启发式规则构造测试Oracle。利用海量数据和启发式Oracle做数据驱动测试。
  3. 迭代地构造Oracle。从简单的规则开始,利用测试结果逐步增强、修改、完善Oracle。
  4. Oracle的输出不是二值的通过或失败。它更像过滤器,其输出是需要进一步人工调查的案例。
  5. 与一些测试方法追求精简的测试用例集不同,测试程序运行尽可能多的测试用例。一方面,自动建议和行车路线的缺陷很难预测,需要大量的测试;另一方面,既然单个测试执行速度很快,为什么不多测试一些真实数据呢?
  6. 充分利用测试工程师的智力。当计算机完成了枯燥的计算,测试工程师可以专注于改进Oracle和调查问题案例,而这些任务是计算机所不能完成的。
  7. 性价比高。在微软总部雷蒙德,一个测试工程师的年薪大约是8万美元。花1万美元,就可以为他配备10台强劲的计算机,而这些计算机至少可以使用3年。因此,合理的测试策略应该是让机器全负荷运转,让人专注于富有智力挑战的任务。

Harry的幻灯片与视频

以下是本文所引用的幻灯片和相关连接:

  1. Harry Robinson的主页:www.harryrobinson.net
  2. 案例1和案例2的来源:Harry在PNSQC 2010的主题演讲“using simple automation to test complex software”的视频幻灯片。内容非常有启发性,强烈推荐。
  3. 案例3的来源:Harry在CAST 2010的报告“Exploratory Test Automation”的幻灯片