UML软件工程组织
北京火龙果软件工程技术中心

选择正确的GUI测试自动化工具

 

来源:51TESTING

概要:GUI (图形用户界面graphical user interface)工具自诩其拥有许多的功能。把GUI测试自动化作为一个编程的项目处理,你将需要一个和你项目大小相当的工具。这是一篇对你购买的GUI测试自动化产品中你所需的关键功能的梗概。

· 在选择一个GUI测试工具需要考虑的因素

· 把GUI测试自动化象一个编程项目一样对待

· 必要功能的清单

购买一个GUI测试自动化工具是一个令人畏缩的任务。如果你是第一次评估工具的话,很难知道要在工具里查找些什么。即使你以前曾经评估过GUI测试工具,那些可用的工具和你上次察看时的情况可能也已经发生了巨大的变化。你会选择哪一个工具呢?你真的需要每个供应商的市场宣传册中吹捧的所有功能吗?你知道你不应该听从那些圆滑的宣传标语。你不确信从现在开始的6个月里你会需要哪些功能。因此你在购买一个可能远远超出你目的的高端工具和购买一个仅仅可以开始作些事情的低端工具之间痛苦的徘徊。

你要做的第一件事情是建立你将在评估工具中使用的决策标准。有一些标准可能是很明显的:你想从一个有信誉的供应商手中购买,你选择的工具需要支持你测试的操作系统,并且容易使用,不管这对你的组织重不重要。这篇文章并不是要告诉你那些你已知的所需功能,而是要说一说在你第一次采购后的几个月里你将发现需要的GUI测试自动化工具中的功能。把它看成是一个对即要发生事情的“预警”(heads up)。

在开始时,思考一下自动化测试系统的概要图形。如果你把测试开发看成是创建一些运行于基于GUI的软件应用程序的测试那样一件简单的事情的话,那么你的测试自动化的模型看上去就像图1。

当你只使用录制和回放时,你的测试将类似于此图。但是这个模型是有局限的。因为测试直接和用户界面一起工作,几乎在UI上的任何变更都意味着每个使用了这部分UI的测试都需要变更。另外,如果有一些大多数测试都必须执行的通用操作(例如,登陆),那么每个测试都必须包括这些步骤。最后,由于在测试中嵌入了所有的测试数据,为了迎合变更,甚至象在登陆表格中的名称这样小的事情,你都不得不编辑测试代码。

结果,做日常维护是非常的困难,并且为本地化或UI检查而做的重大变更更是一个恶梦。象这样的测试系统在一个单独的版本里彻底崩溃可不是罕见的。换句话说,在1.0版本中可以运行的测试,但在2.0中你可能就需要再创建它们了。

为了说明每个缺点,让我们增加一些更多的元素。在后面将会详细的解释每个元素。首先,在所测试的软件和测试脚本中增加一个抽象层。抽象层把UI元素映射为测试将使用的逻辑名称。接下来,增加一个可重用的函数库以封装常用的操作。最后,增加测试数据文件以保存否则可能被硬编码在脚本中的数据。现在这个模型看起来象图2。

即使你没有计划使用在这个图中的所有元素,你都要寻找一个可以支持所有这些元素的工具。你会在比你想象中更早的时间里需要这些功能。

为什么呢?当你创建一些快速的,低劣的并且为任意使用而设计的测试时,你的自动化测试工作量是不太可能得到回报的,除非你的测试大部分是:

·可维护的:从一个版本到另一个版本都是可用的,只是为了新的功能或新的UI而做少量的更新

·可靠的:提供准确的结果,它对于识别所测试软件中问题是直接了当的

·健壮的:能够处理异常的错误条件,使测试可以在没有人工干涉的情况下运行。

只有当你将测试自动化象软件开发一样认真的对待,你才能达到那个目标。测试自动化实际上就是编程。因此一个好的GUI测试自动化工具将拥有许多和一个好的开发环境相同的功能。

“噢,当然”你可能会想。“我将在我的大量的空闲时间里开始编写我的测试。”你或许刚刚好有足够的时间完成你现在的任务。自动化被假设为可以使你的生活更加轻松,而不是增加一个全新的编程任务。不幸的是,如果你不将测试自动化看待为一个编程任务,你将无止尽的重做,重做,重做。更糟的是,如果在项目的末尾时,最后一分钟的变更破坏了测试,那么已自动化的测试将不能够运行-刚好在你最需要它们的时候。即使你认为你没有时间在多数的测试中遵循优秀的开发实践,也应该购买一个支持它们的工具。把它看成是一个保险措施。

因此你可以怎样确信你已经识别了一个将使你能够构建一个系统并利用优秀的编程实践实现它的工具呢?让我们来看看在任何优秀的工具中都很重要的12个功能。

功能检查表

1). 脚本语言

本文中描述的其他所有功能的一个先决条件是工具必须有一种包含了常见编程构想的脚本语言。至少,它应该:

·使你能够编辑已录制的脚本

·支持变量和数据类型

·支持矩阵,列表,结构,或其他复合的数据类型

·支持条件式的逻辑(IF和CASE语句)

·支持循环 (FOR, WHILE)

·使你可以创建和调用函数

如果工具使用的是象VB或C一样的常用语言,你会获得一个附加的好处:很容易找到这些语言的书籍或培训课程,并且在你组织中的大多人可能已经知道它们。

语言越强大,你潜在拥有的控制就越多。成熟的脚本语言使你能够创建更加成熟的脚本。当然,拥有一个复杂语言也使创建比所测软件更复杂的自动化测试变为可能。因此寻找一门可以带给你所需的力量和灵活性的语言,并且为使用这一先进的功能明智地设计你的测试。

2). UI元素识别器 element identifiers

为了编写真正的可以测试一些东西的测试脚本,你应该确信测试工具能够把UI上的元素识别为对象,而不是试图通过坐标指向它们。

如果你正在测试一个Windows的应用程序,并且开发人员正在使用MFC (Microsoft Foundation Class library) 控件的话,那么大多数可用的测试工具就都没有什么问题。然而,如果你的应用程序是使用Java Swing控件(a.k.a. JFC,或 Java Foundation Class library)编写的话,有些工具会比其它的工具工作地更好。在评估期间,确信工具可以识别多种典型窗口中的UI元素。

有些UI元素根本不是真正的控件,这是真的,它们只是一些当你点击它们时可以作些事情的位图。使用位图UI元素比使用那些不能和任何自动化测试工具一起运行的真正的控件更好。如果你的软件是这种情况的话,在工具评估时把开发人员一起叫来以便他们可以第一时间看到为什么使用标准的控件对于提高软件的可测试性是很重要的。

3). 可重用的库文件Reusable libraries

设想你正在测试一个允许你查询数据库中记录的应用程序。许多产品的功能只可以在有一组可用的查询结果的情况下工作,因此大部分的测试都要包含执行一个查询所需的步骤。现在试想一下轻微地改变一下步骤的顺序:你需要更新每个脚本。

可供选择的方法是创建一个执行查询的函数或子程序。这个函数变成了一个可重用库文件的一部分。每个脚本调用这个函数比重新定义那些步骤更好。如果你在一个地方(函数库中)定义了事件的进展,你将使你所有的脚本更加好维护,这样胜于在需要执行这些操作的每个脚本中定义它们。

为了寻找一个支持可重用库的工具,有两件重要的事情需要做。首先,要确保你用工具创建的脚本能够轻松地调用你放在库文件中的函数。如果工具只允许你调用在当前脚本中创建的子程序那是不足够的。第二,确信函数可以带参数。例如,如果你创建了一个登陆的函数,你想要在每次调用函数的时候指定用户名和密码(而不是在函数中嵌入这些信息)。

4). 外部的库文件Outside libraries

除了创建你自己的库文件之外,你通常会发现访问外部的库文件是非常有用的。在Windows里,这意味着你应该能够调用.dll文件。举个例子,思考一下一个已构建的与关系数据库一起运行的C/S系统。所测试的软件使用了数据库私有的API(Application Program Interface)。如果自动化测试可以使用相同的API,它们可以变得更加强大。他们可以检查不允许访问的用户界面。例如,它们可以检查一个已更改的值是否已经被写到数据库中,而不仅仅只是在屏幕上更改了。即便UI没有给权限给它们记录,它们都可以检查交易是否成功并且完全被记录了。一般说来,这些测试可以比通过验证UI上的值更加准确地判断“成功”或是“失败”。

如果你正在一个Windows系统上测试,你也应该有访问Windows API的权限。Windows API 使你能够获得系统信息,这是非常困难的或者其他方法不可能获得的。例如,在你的自动化脚本中获取或设置注册表的键值的时候是非常有用的。

5). 抽象层Abstract layers

一个“抽象层”使你能够为物理的用户界面元素定义逻辑名称。一些工具称它为“test map” 或“GUI map”,也有些称其为“test frame”。不管它叫什么名称,抽象层的目的就是使维护测试变得更轻松。

举个例子,想象一下带有用户名和密码字段的登陆对话框。在程序里,编程人员命名这些字段为“Name”和“Password”。你创建一个抽象层,它也将那些字段识别为“Name”和“Password”,并且在你所有的500个测试中都使用这些标志符 。但是随着所测试软件下一个版本的出现,名称和密码字段的潜在标志符变成了 “username”和“pword”。你只要在一个地方-抽象层中更改UI标志符,而不是在你所有的500个脚本中做变更。

几个测试工具都提供了这样的功能,例如窗口录制器,它是特别设计的以支持一个抽象层的创建。这些功能是非常有用的,但是如果你愿意手工的编写抽象层,这也不是绝对需要的。

6). 分布式的测试Distributed tests

如果你正在测试多用户的软件,你需要能够创建包含多个模拟用户的测试。 例如,你可能想创建一个某台机器上的用户锁住一个文件而另一台机器上的用户又在试图打开同一个文件的测试。你如何自动化这种类型的测试呢?如果你选择的测试工具没有分布式测试的能力的话,那么这将是很困难的。

在一个分布式的测试里,自动化测试工具使你能指定执行一个既定指令的机器。这和在一台远程的机器上完成一个测试的能力(这也是一个很好的功能)有些不同。在一台远程机器上开始测试,远程机器从头到尾完整地运行那个测试。但是如果你需要在两个不同的机器上协调这一活动,那么你应该做比只是开始一个测试且让它运行更多的事情。你需要能够创建一个等待一个动作的测试(例如锁住一个文件),以便在第二台机器开始一个动作之前(例如试图打开文件)在第一台机器上完成操作。

7). 文件I/O

文件的I/O (输入/输出input/output)意味着工具提供了让你通过编程打开硬盘中的文件,读取文件,写文件和关闭文件(通常是一个ASCII文件)的函数 。

文件I/O函数是“数据驱动测试自动化”的核心。在一个数据驱动的自动化测试里,脚本使用文件中的测试数据来驱动测试活动(注意在图2中“测试数据”在测试自动化架构中的角色)。数据驱动测试使自动化大量的测试,却只有少量的测试自动化代码变为可能。

如果你正在测试一个Windows的系统,如果工具提供了处理.ini文件的函数,那是特别有用的。例如,如果所测试软件需要知道正在使用哪个服务器,那么在.ini文件中指定服务器的名称是一个很好的方法。于是你只需要在文件中更改测试服务器,而不需要更改自动化脚本。

8). 错误处理Error handling

在你昨天晚上离开之前,你开始了一个很长的,需要运行250个测试的自动化测试。你来到的第二天早晨,你发现那些测试只运行5分钟,因为在运行第二个测试之前出现了一个意外的对话框。这是个令人沮丧的场景,而且从来不少见。

拥有一个优异的错误处理系统的工具使得其他的脚本可以继续运行,甚至于一个脚本失败之后。工具可以停止失败的脚本,然后在开始下一个脚本之前重新设置软件到它初始的状态。

如果工具的错误处理能力可以定制的话,那是非常有用的。例如,或许你的产品有已知的的错误条件,它需要一定数量的清除以修复。如果你能够扩展错误处理系统以便它可以识别那些错误并且执行所需的清除,你的自动化测试甚至可以更加得健壮。

9). 调试器The debugger

没有比“该死,它应该是可以工作的” 的感觉更令人沮丧的事情了,你完成了你的测试并且成功的使它运行在你的机器上了。现在你试图运行测试在其他人的机器上,而它却不能运行。拥有一个好的调试器可以比试验-错误方法使你更快的发现问题。

调试器是嵌入在测试脚本开发环境中的,通常调试器使你能够一步步的按行执行脚本,设置“断点”(调试器可以停下执行脚本并且等待下一个指令的地方),并且检查当前定义的变量和它们的值。如果调试器能够让你在任何可执行行上设置断点那将更好,不管它是在所测试的脚本里还是在支持的代码中(例如,在可重用的库文件)。

10). 源代码控制Source control

源代码控制是一个任何类型软件开发的基础性工具,因此测试自动化也不例外。一般来说,源代码控制系统允许你从一个主库中check in或check out文件,回滚到先前的版本,找出版本之间的差异,并且同时追踪几个项目。这些功能使得多个人工作在源码文件的多个版本上变为可能。

与其寻找一个包括了源代码控制功能的测试工具,不如使用和软件开发人员所使用的一样的源代码控制系统,实际上这样也会更好些。使用相同的源代码控制系统的实用性好处是你可以利用已经有一个建立了的工作方式的事实。使用相同的系统还有心理上的好处:在你组织的其他人了解到测试自动化是“真正的编程”。

即使你是你团队中唯一的正在做自动化测试的人,你仍然要确信你所构建的测试系统中的所有部分-从测试数据文件和测试脚本到抽象层-可以在源码控制下进行。幸运地是,和源代码控制系统集成是比较简单的:如果测试自动化文件用ASCII存储,你可以使用你源码控制系统中的所有功能。用二进制格式存储自动化测试任何部分的测试工具会妨碍你和你的测试一起使用源码控制的能力。你仍然可以把二进制文件放到源码控制中,但是你将不能把文件的一个版本和另一个版本对比以判断文件做何变更。(如果你不确定的话,你可以通过用好像Windows中的Notpad文字处理器来打开文件以断定它是否是ASCII。如果你只看到文字字符并且有些意思,那么文件就是ASCII的。如果取而代之的是看到笑脸,心形,方块或其他的奇怪的字符,那么文件可能就是二进制的了。)

另外,如果测试工具需要你将所有的文件放在一个集中的地方并且规定文件的结构,你需要试验一下以确定和集中的文件位置一起使用源码控制的最好方法(最好是在评估期间)。

11). 命令行脚本执行Command line script execution

从命令行运行脚本的能力使得设置脚本更加地容易,在机器comes back up之后自动地重启机器和重新开始测试。这也使在每个版本后自动地开始自动化测试成为可能。

12). 用户社区The user community

最后一个要查找的功能在软件盒中是找不到:寻找一个拥有已建立用户社区的工具。讨论组,用户的网站和当地用户团体是所有可以学习你新工具细节的好地方。用户社区的成员常常会共享通用函数的库文件或其他一些有用的源代码-这样为开发你自己的内部可重用的库文件有很大的帮助。

在你购买大量license之前先购买一些

就大多数组织而言,转换工具的成本是非常昂贵的。那不仅仅是购买新软件的事情。它也是关乎是要用新的工具重新创建现有的测试还是继续为现有的工具支付维护费用的事情。购买一个受限的试用版的一个或两个license,可能是在没有太大风险的情况下试验工具的最好办法。如果试用版运行的很好,那么就购买更多的license并且全力的投入。如果试用版运行的不好,至少你没有购买太多的license,潜在地浪费了很多的钱。

这也意味着如果你现在有一个工作的相当好的工具,但是没有本文提及的所有功能,不要马上跑出去买一个新的工具。切换工具可能比你相象中更加地昂贵。

结论

评估自动化测试工具是特别困难的,因为大部分的测试工具供应商在试图做成买卖时,强调易用功能多过编程功能。你不会发现工具不能和你的源代码控制系统一起工作,或是脚本很难维护,直到上路的6个月后。寻找与你现在所需功能,将来需要功能相平衡,以及迎合你预算底线成本的工具,这的确是一个挑战。

另一个挑战存在于间接地分开现实和市场。在你评估期间,你要确信花了时间研究手头上工具中比较先进的功能。换句话说,不要依赖功能列表来决定你需要的最好工具。应该亲自动手使用产品,并且使它自动化真正的测试。

记得在购买新的工具的时候,重要的是不管供应商想使测试自动化看上去怎样得简单,它实际上就是编程。相应地选择工具。当你为最新的版本更新你的测试包时,你将会知道它是非常的值得,并且将发现你有一个比你曾经想象的更快的完整的测试包。



版权所有:UML软件工程组织