解决多通道测试的挑战

在界面间移动的测试,从移动到 Web 再反转回来

Comments

多通道 描述的是具有多个界面的应用程序。随着我们从桌面发展到基于 Web 的计算甚至是移动计算,多通道越来越常见。由于设备(平板、手机、笔记本电脑、台式计算机)以及与设备交互方式(特定于设备的 “应用程序”、浏览器和传统的客户端应用程序)的组合,同一个应用程序的界面越来越多。比如,使用相同业务逻辑的面向 Web 应用程序、移动应用程序甚至是一个 CLI(命令行界面)的银行应用程序。由于面向服务的架构 (SOA) 和 Web 服务日益流行,在很多情况下,集成者要做的工作就是把服务与新的前端重新组合。但业务逻辑(亦称服务)则保持相同。

以开发团队重用代码来减少维护成本并提高生产效率相同的方式,要跟上开发团队,测试团队就需要一些方法来重用测试场景并实现自动化。

应对多通道测试的挑战

几年前,我是一名自动化测试架构师,负责为具有多个界面的两个(而不是一个)应用程序构建所有的自动化。二者都有遗留的 “本地” 用户界面,使用的是 Microsoft Windows 32 位 MFC (Microsoft Foundation Class) 控件、一个使用了 JavaScript 的 Web 界面、ASP 和 JSP(Active Server Pages 和 JavaServer Pages)、一个新的(更新的)Eclipse SWT (Standard Widget Toolkit) 界面以及一个命令行界面。当然,不可能找到对所有这些界面均有效的自动化工具,但我们可以暂时将其放到一边。

编程时,您往往会专注于通过促进重用减少需要维护的代码量。有了面向对象的编程和重构,很少有理由需要在多个地方具有相同的代码了。但是需要设计一个架构,这样我就可以考虑如何从一个单一的测试自动化代码库解决多个界面的测试。首先,尽管它们是同一个应用程序的所有界面,但并不是所有的界面都会浮现相同的功能,更不用说使用同样的方式了。但也有许多以客户为中心的场景(用例),这对跨所有界面进行测试很有意义。

然而,负责设计测试用例和测试计划的测试团队没有以这种方式考虑他们的测试。事实上,他们是分离的,并根据他们所要处理的界面以竖井方式分离。构建并测试了该 CLI 的团队认为他们只需要少量的客户场景测试。他们主要集中于单元测试,并没有真正考虑通过 CLI 的一个客户流。负责 Eclipse UI 的测试团队想要大量的 UI 特性和自动化的功能。他们有一长串需要执行的测试用例,要实现这个目标,需要完全专注于客户流。但是,我们为什么就不能使用由主题专家 (SME) 为应用程序煞费苦心完成的用来测试所有界面的这些信息呢?

一种层次结构方式

使用面向对象的编程 (OOP) 的典型测试自动化框架一般会抽象化控制集的实现细节,而不是通过控件表达的概念性操作。这实际上是许多商业 GUI 自动化工具使用的方式。例如,所有文本字段会接受文本,用 setText(string) 方法定义一个文本字段类,并在此应用程序的所有版本上使用它。但这并不适用于跨界面构建自动化测试的所有情况。当一个 GUI 使用单选按钮而另一个使用复选框时会发生什么呢?您实际上不能对于相同操作依靠于同一界面。以下显示了这种传统的 OOP 方式。

图 1. GUI 控制层次结构
顶级的文本字段 setText(字符串为 arg0)
顶级的文本字段 setText(字符串为 arg0)

在我们的示例中,界面的差异很大,但所代表的操作和业务流程则实质上相同。为了最大化重用,我们选定了一个业务逻辑层次结构(参见图 2)以跨多个界面重用测试场景。这不仅能最大化我们的代码重用,还意味着将会依赖测试工具来管理 GUI 界面,而这正是他们的设计初衷。图 2 显示了此方式,您可能已经识别出了这个抽象工厂模式。

图 2. 业务逻辑层次结构
顶级的核心应用程序、抽象类
顶级的核心应用程序、抽象类

通过采用业务逻辑的方式,通过应用程序的每个流都可以表示成操作集,而操作又被定义为抽象类上的方法。虽然每个界面都可能在操作内具有一些不同的步骤,但它们都允许、理解和需要这些相同的操作。这就相当于为了测试而构建一个特定于应用程序的测试框架来代表测试业务任务下的这个应用程序。这种方法意味着要定义一组对象,在应用程序中执行操作所需的数据和信息就可以封装在对象之中。然后,我们需要在这些对象内定义一组方法来描述操作,并收集操作专门需要的任何额外的数据,如图 3 中的代码片段所定义的。

图 3. 抽象类的代码示例
代码示例的屏幕截图
代码示例的屏幕截图

以文本表单格式查看图 3 的代码

Query 是一个抽象类,收集创建和执行查询所需的有趣数据,以及有趣操作,如运行、创建、编辑和重命名。重命名方法需要新名称的额外参数,但当它成功后,会自动更新此查询对象的名称值。在这个级别对用户界面没有假设。用户界面的细节只在特定于界面的具体类内表达。要在一个给定的界面上执行,需要在运行时为每个界面实例化一个具体类并调用此操作,具体类似于如下所示:

Query myQuery = (parent_location, findRecords);
myQuery.rename(renamedQuery);

基于应用程序的框架

定义用来描述测试所需操作的抽象业务逻辑类的一个后果是可以将所定义的方法重组成新的流。此外,还可以指定在运行时运行哪个界面。这是一个强大的组合,可以完成几件事情:

  • 针对此应用程序的操作只定义一次
  • GUI 元素只被发现和处理一次
  • 为一个界面设计的测试场景可以在另一个界面上运行
  • 因重用的增加,维护显著减少

当然,这其中的诀窍是在每个要测试的界面内如何对任何给定的操作进行编码。这需要面对大量的工作,但在一个界面完成后,有许多测试脚本可用于任何其他的界面。而这就是必须为每个后续界面要实现的全部步骤:

  • 添加在该界面上执行操作所需的实际步骤
  • 补充此框架来涵盖其他界面内所没有的任何功能

该方法的另一个好处是:尽管仍然被表示为代码,但它在一个足够高的抽象级别可读取为伪代码,这对非编程人员 SME 很有意义。这让非编程人员能够创建新的自动化脚本,以及运行和理解自动化团队所交付的测试脚本。

清单 1 是与 Eclipse 视图交互的一个示例代码。

清单 1. 与 Eclipse 视图交互的代码
Perspective resource = new Perspective("Resource");
Perspective general = new Perspective("General");
app.start();
EclipseView bookmarks = new EclipseView("Bookmarks", resource);
EclipseView explorer = new EclipseView("Project Explorer",general);
resource.open();
resource.reset();
bookmarks.open();
explorer.open();
bookmarks.switchTo();
explorer.switchTo();
bookmarks.maximize();
bookmarks.restore();
bookmarks.minimize();
bookmarks.restore();
bookmarks.close();
resource.reset();
app.exit();

采用这种方法可以降低维护成本,并能确保对于 GUI 的任何部分,在自动化测试代码内都只需在一个地方进行调整。但这种方法的好处只有在 CLI 上实现了进行业务逻辑的具体步骤之后才会变得真正清晰。

负责测试该特性的团队已宣布 “完成”,且没有明显的缺陷。自动化的实现是为了为未来版本确保一个回归测试套件。但是当我们运行用来针对此 CLI 实现测试 GUI 的测试脚本时,就会发现 50 多个缺陷!这些都是重要的缺陷,肯定会被我们的客户发现。

作为测试人员,我们总是很兴奋能首先发现缺陷,因为早期发现问题能明显节约成本。另外,构建不只能验证产品稳定性的测试自动化也很令人兴奋。同样重要的就是信誉、既有的顾客满意度,以及此测试自动化所带来的整体质量改进方面的商业利益。

如今的多通道测试

在上述的项目过程中,我们可以在运行时只选择一个界面。一个测试脚本必须是完全自动化的,且必须要有为每个需要测试的界面实现的一个完整的业务逻辑操作集。这种方式在当时是合理的也是可以接受的,这是因为最终用户一般不会在一组操作期间从一个桌面客户端切换到一个 Web 客户端。

但时过境迁。现在考虑一个可能开始于 Web 客户端、穿过一个移动应用程序、然后再回到 Web 的测试场景,甚或是一个针对数据库后端的独立验证已不再符合实际了。

考虑这样一个场景:有人在 eBay 竞价。使用一个台式计算机和浏览器(Web 客户端)对商品进行搜索和研究更容易。一旦决定了想要的商品,就可以进行竞价。您可以离开计算机,并在您的智能手机收到一个通知,告知您竞价胜出,于是您从手机上更新出价。当赢得竞价时,您再回到计算机前,在浏览器中输入付款信息。

这是一个测试场景,与其从屏幕上此界面的一个部分(使用屏幕抓取或对象属性)中验证交易的成功,还不如直接使用数据库并检查记录。这种独立于界面的验证更健壮,也更稳定。我们可以把这种方式称为 “混合” 测试场景。并且,从理论上来说,当自动化一些产品区域太难(或过于昂贵)时,混合场景应该允许混合进手动测试执行来提高测试覆盖率。

所以,我已经开始幻想如何能实现这样一个流,于是我将不同的界面和操作实现拼装成一个能在界面之间无缝移动的复杂流。可以肯定的是,的确存在挑战,并且挑战可能会不可逾越。而了解了当运行时环境受制约时哪些数据在操作间移动则会相对简单得多。而当跨越界面时,哪些数据可能需要在操作间传输则不能立即清晰。使用上面的示例,将需要先登录到一个 Web 客户端和移动电话。身份验证明显是个问题,但实现这些混合测试场景注定会有很多并发问题。

但没有关系,那不过是一个珠穆朗玛峰。让我们出发吧!通过加入 LinkedIn 上的 IBM Rational Functional Tester Network 讨论组 参与讨论,或对本文提出建议来告诉我们您的想法,或添加您的意见。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=931580
ArticleTitle=解决多通道测试的挑战
publish-date=05272013