本文是《使用Sahi测试Dojo应用》的延续。在《使用Sahi测试Dojo应用》中,我们谈到了ITCL架构(应用对象层,任务层以及测试用例层)。本文向大家介绍如何编写一个Sahi的脚本以自动生成应用对象层的代码从而简化和加速Web自动化测试用例的开发。 一.概述 之所以有可能开发一个Sahi脚本来生成应用对象层的代码,主要得益于以下几个方面: 1)面向对象设计模式的应用 Dojo本身将页面中的控件用面向对象的模式封装成不同的widget,而本测试框架用不同的Javascript的函数映射到不同的Dojo的widget。这样的一种设计模式,使我们有可能通过搜索页面中的Dojo widget以自动生成用来实例化页面控件的代码。 2)强大的Dojo query以及Sahi的基于上下文的API 在后面的代码详解中,大家可以看到我们是如何借助Dojo query以及Sahi的基于上下文的API来搜索页面中的Dojo widget的。并且,由于Sahi本身支持browser端的Javascript的脚本,因此在我们的代码中可以方便地将Dojo API和Sahi API混用。 3)Sahi的基础-Rhino 因为有了Rhino的支持,Sahi可以进行本地文件的读写,因此使我们能够将生成的结果以文件的形式保存下来。甚至,如果需要的话,我们可以实现基于文件的代码生成模版管理。(关于代码生成模版管理,本文所附带的示例代码没有包含该功能,如果读者感兴趣可以自行尝试)。 简单来说,代码生成Sahi脚本的工作过程如下: 1.为每种Dojo widget定义一个Javascript函数。该函数的功能是为特定widget代码生成提供元数据。 2.使用者在调用代码生成函数时,可以传入一个数组以指定要生成的widget的名称,比如按钮、输入域等。默认,代码将生成所有支持的widget类型。 3.当代码生成函数被调用时,它使用Dojo query遍历DOM tree以搜索Dojo widget的最外层元素(通常是DIV并包含widgetid属性)。之后,将该元素交予具体的处理widget的函数生成声明代码。 4.如何知道通过何种方式可以实例化找到的Dojo widget呢?在Dojo widget函数的公共“父类”中,定义了若干“猜测”函数,例如guessByName、guessById以及guessByLabel。如果需要的话,具体的widget函数可以定义自己的“猜测”函数,例如DojoButton函数就定义了自己的guessByText函数(因为这个函数不具备通用性)。“猜测”的入口是一个叫guess的函数,具体的widget函数可以传递给guess一个数组以指定“猜测”的优先顺序,例如,[this.guessById,this.guessByLabel]就表明先检查widget有没有id属性,如果有就生成通过id实例化widget的代码,如果没有的话,就继续尝试“猜测”label的方式。如果所有的“猜测”函数都失败,就在Sahi的log中打印出一条信息,告诉调用者,无法生成这个widget的实例化代码。 5.最终,把所有生成好的代码语句拼接成一个字符串,保存到generated目录下的appobjscode.sah文件中。同时,这段代码也会打印在Sahi的log文件中。 二.如何运行代码 用来生成应用对象层代码的脚本位于压缩包的sahidojodemo/codegen目录中,有codegen.sah和main.sah两个Sahi脚本文件。codegen.sah定义了代码生成的核心逻辑而main.sah只是对其进行调用。我们使用的示例页面依旧是http://demos.dojotoolkit.org/demos/form/demo.html。读者只需在该页面上弹出Sahi控制器并运行main.sah脚本即可。下面是该脚本的运行效果图。 若要测试生成的代码是否工作,只需要把上图生成的代码粘贴到appobjs/ JobAppFormPage.sah中并运行run.sh。具体的操作步骤请参考《使用Sahi测试Dojo应用》的“如何运行示例代码”部分。 三.代码详解 下面对代码进行详细地解释。 1.函数概览 在codegen.sah中有如下一些函数(或者称做“类”)。 WidgetMetaData:定义全局widget“元数据”的结构。它包含widget名称、搜索模式以及处理“类”的名称三个属性。 AppObjsCodeGen:负责遍历页面搜索widget、调用相应的处理“类”生成代码并格式化代码。 DojoWidget:负责代码生成的核心逻辑。定义公共的“猜测”函数。 DojoTextbox:“继承”自DojoWidget。提供输入域widget的元数据。 DojoSlider:“继承”自DojoWidget。提供滑块widget的元数据。 DojoCombobox:“继承”自DojoWidget。提供下拉框widget的元数据。 DojoButton:“继承”自DojoWidget。提供按钮widget的元数据。 2.元数据的定义 元数据的定义分为两部分。第一部分是一个metaData的数组,它用来声明所有支持的widget类型,数组元素是WidgetMetaData。第二部分就是映射到每种Dojo widget的Javascript函数,如DojoTextbox等,它们提供了特定widget的元数据。 |