JavaScript工具

JavaScript工具

开发软件可能十分困难,这早已不是什么秘密。与其他领域不同,软件开发并不会制造出有形的三维产品,可以让我们拿在手里感觉并审视。不管我们花多少时间来画类图或设计流程图,最终我们都得编写代码。今天,开发软件系统需要编写大量的源代码。即使是我们自己设计软件,并且在大多数情况下是我们自己编写代码,用不了多久,源代码的数量也会轻易地超出我们所能控制的范围。面对现实吧:我们需要帮助。

幸运的是,不断完善的开发工具大大减轻了开发人员的负担。源代码编辑器、调试工具等正使构建和调试大型软件系统变得简单。

在本章中,我们将研究一些能够简化Ajax开发的工具。幸运的是,我们能够利用很多你可能在日常的Java开发中已经在使用的工具和技术。

2.1  JavaScript源代码编辑器

很多人都使用某种IDE(集成开发环境)来编写Java程序。是的,用最简单的文本编辑器和命令行式的编译器也能编写Java程序。但是,我们确实都从现代IDE所提供的强大生产力中获益匪浅。

如果你正在阅读本书,那么很明显,你使用Java来编写Web应用。基于Java的Web应用不仅仅包含Java源代码文件。使用Java EE平台构建的Web应用包括Java源代码文件、HTML和XHTML文件、XML文件,甚至纯文本文件。现代IDE可以管理所有这些文件,这就减少了构建Java EE应用所要使用(并学习!)的程序的数量。

有多少人愿意阅读整页整页的源代码呢?更糟糕的是,如果源代码不是我们自己编写的,因而我们对它并不熟悉,那该怎么办呢?智能的源代码编辑器中一个很方便的功能是突出显示关键字。这是一种你可能会发现它很方便但很少会仔细考虑的功能。在能够突出显示某种语言的关键字的编辑器中阅读源代码显然要舒服得多。

如果没有现代IDE,面向对象开发几乎不可能成为现实。想像这样的场景,你在编写位于一个对象继承结构中的类。你想编写一个方法,但是不知道父类中是否已经定义了这样的方法。怎样才能弄清楚这一点呢?最耗时的办法就是去查看父类的源文件。你可能会发现父类中没有这个方法。但是父类的父类中有没有呢?你可能要不断地打开对象继承结构中的每个源文件。这可是既单调乏味又十分耗时的活儿。

更糟糕的是,如果你没有对象继承结构中的所有类的源代码的话,该怎么办呢?突然间,你不能浏览源代码文件了。查看Javadoc怎么样?浏览Javadoc也是很慢的,而且还要假设有Javadoc可用。

软件开发史上最大的生产力改进毫无疑问就是智能代码完成,如今它已经成为几乎每个Java IDE的标准功能。如果你不清楚一个类中有哪些方法或属性可用,只需使用IDE的代码完成功能,就可以弹出一个包含所有可用方法和属性的列表,允许选择想使用的那个方法或属性。更妙的是,很多编辑器甚至能在代码完成列表中加入所有可用对象和类的列表。这种智能代码完成不仅减少了搜寻源代码的时间,而且它还减少了我们的代码键入量,这间接减少了可能发生的代码键入错误,后者又间接减少了编译的失败。

为什么要谈Java IDE呢?事实上,你很可能已经感受到了使用智能IDE编辑Java源代码所带来的巨大的生产力提高。既然Ajax正在成为开发人员工具箱的一部分,你将会比以往编写更多的JavaScript。这当然就引发了这样一个问题:有可供JavaScript使用的智能代码编辑器吗?

简而言之,答案是有。但是JavaScript编辑器并不像Java编辑器那么先进,虽然随着Ajax和JavaScript开发的成熟,它们会逐步完善。很多编辑器已经提供了一些简单的功能,比如关键字突出显示。

当今大多数流行的Java IDE——Eclipse、NetBeans和IntelliJ IDEA——都提供对编辑JavaScript源代码文件的支持。在写作这本书的时候,IDEA已经内置支持JavaScript源文件了,而 Eclipse和NetBeans则以插件的形式提供了对JavaScript的支持。在本节中,你将看到如何为Eclipse和NetBeans安装并配置JavaScript插件。

2.1.1  JSEclipse

InterAKT提供的JSEclipse是最先进的JavaScript编辑器之一。JSEclipse是针对Eclipse开发平台的免费插件。它支持的功能有:代码完成、大纲浏览、错误报告、代码换行,等等。

多亏了Eclipse的插件架构,JSEclipse的安装非常简单。选择Help→Software Updates→Find and Install,打开Eclipse的插件安装向导。选择Search for new features to install并单击Next。

现在, Install窗口就应该出现了。单击New Remote Site按钮,并在弹出窗口的Name文本框中输入InterAKT Online,在URL文本框中输入http://www.interaktonline.com/,然后单击OK按钮。现在,安装窗口应该如图2-1所示,其列表中应该包含InterAKT Online。

需要注意的是,JSEclipse需要Java 1.5或更高版本。对余下的安装步骤统统单击Next就可完成JSEclipse的安装。之后,重新启动Eclipse,确保插件安装正确。

图2-1  把InterAKT Online添加为远程站点后的Eclipse Install窗口

安装好 JSEclipse之后,就可以开始编写JavaScript了。JSEclipse把所有以.js为扩展名的文件都识别为JavaScript源文件。选择File→New→File,并输入一个以.js结尾的文件名,就可以创建一个新的JavaScript源文件。创建好新的JavaScript源文件后,就可以开始编写JavaScript代码了。

在JSEclipse中编辑JavaScript时,你首先会注意到的就是它所提供的JavaScript关键字突出显示功能。同样需要注意的是,Outline视图中会包含JavaScript代码的大纲,显示出源文件中定义的对象所包含的方法。

图2-2 展示了在JSEclipse打开的JavaScript源文件。项目中有两个JavaScript文件:Department.js和 Employee.js。在源代码编辑器中打开的是Employee.js文件。在窗口左端的Navigator面板中的JavaScript文件有它们自己的图标,当前打开的源代码的大纲被展示在窗口右端的Outline面板中。

JSEclipse 能做的不仅仅是这些。就像之前讨论过的那样,一直以来最具生产力的功能之一就是智能代码完成。JSEclipse为用户自定义的JavaScript对象提供了智能代码完成功能。图2-3演示了这种代码完成功能。Department.js文件含有一个简单的函数用来创建Employee对象的一个实例。然后,可通过圆点符号获得这个对象的方法。当键入圆点符号时,JSEclipse会自动显示代码完成窗口。

图2-2  JSEclipse源代码编辑器

图2-3  JSEclipse提供对JavaScript对象的代码完成

JSEclipse也提供对内置的JavaScript对象的代码完成,如Date、String、document和window,等等。

JSEclipse 还提供扩展其自带的代码完成功能的方法。可以编写一个简单的XML文件,在其中定义对某个类型的对象应该出现的代码完成列表。事实上,默认的 JSEclipse发行版本就使用XML文件定义其对内置JavaScript对象的代码完成。代码清单2-1列出了object.xml文件的内容,这个文件就定义了对基本JavaScript对象的代码完成。

代码清单2-1  object.xml为基本JavaScript对象定义代码完成

这个 object.xml文件放在JSEclipse安装目录的library目录中。在这个目录中,还可以找到定义了各种JavaScript对象的代码完成的XML文件。可以修改这些文件来满足你的需要。更妙的是,可以创建自己的XML文件,描述你已经编写好的JavaScript文件。可以为在你的组织中共享的JavaScirpt文件编写一组XML文件来提供代码完成功能。JSEclipse的帮助中给出了一个创建自定义的代码完成库的很好的例子。打开Eclipse的Help菜单并找到JSEclipse extending the code completion一节,就可以访问到这个教程。

JSEclipse是一款强大的JavaScript编辑器,它可以简化JavaScript的开发。随着Ajax和JavaScript变得越来越主流,开发工具会变得越来越完善,但是从目前来看,JSEclipse是JavaScript编辑器的不二之选。

2.1.2  NetBeans的JavaScript插件

在写作这本书的时候,NetBeans的最新版本5.0并不提供对JavaScript源文件的内置支持。不过,NetBeans的使用者和贡献者Nicolas Désy为NetBeans开发了一款支持JavaScript源文件编辑的插件。

这个插件的主页是www.liguorien.com/jseditor。在那里可以找到更多关于插件功能的信息,可以从那里下载到这个插件。

Nicolas说这个插件只不过是在NetBeans内置支持JavaScript源文件之前的权宜之计,并且不会对这个插件做进一步的开发。不过,这个插件确实为工作在NetBeans环境下的开发人员提供了一些不错的功能。

1. 安装

有两种方法可以安装这个NetBeans插件。第一种方法是把插件的主页注册为NetBeans的一个更新中心,并从那里安装插件。第二种方法是手动下载并安装插件模块。两种方法比较相似,这里我们将演示使用手动下载的文件来安装。

访问插件的主页,并单击指向NetBeans JavaScript Editor二进制版本的链接。这会下载该插件模块,该模块具有.nbm扩展名。

下载好插件模块之后,启动NetBeans并从Tools菜单中选择Update Center菜单。这会打开Update Center Wizard,该向导会引导你完成插件的安装过程。选择Install Manually Downloaded Modules单选按钮并单击Next。在下一个窗口中,单击Add按钮,并选择下载的.nbm文件。单击Next按钮。

下一个窗口展示了将要被安装的模块,如图2-4所示。其中,JavaScript editor应该已经被选中了。

图2-4  安装NetBeans JavaScript Editor插件

单击Next按钮并接受许可协议,然后在下载窗口中单击Next。在最后一个窗口中,选择Include复选框并单击Finish按钮,这样,安装就完成了。重新启动NetBeans,现在就可以使用这个JavaScript编辑器了。

2. 功能和用途

NetBeans JavaScript Editor把所有扩展名为.js的文件都识别为JavaScript源代码文件。通过选择File菜单中的New File菜单项然后选择JavaScript分类,就可以创建一个新的JavaScript源文件。编辑器支持突出显示所有JavaScript关键字的语法,以及突出显示配对的大括号和小括号,并提供标准的DOM对象(如document和window)的基本代码完成。使用组合键Ctrl+Space 可以调用代码完成功能。

该JavaScript 编辑器的一个最好的功能就是它会格式化JavaScript源文件。有多少冗长的JavaScript源文件是那样难以阅读,只是因为其糟糕的格式和缩进?在该JavaScript编辑器中,你可以通过组合键Ctrl+Shift+F重新格式化整个JavaScript源文件。

这个功能的实际效果如何呢?图2-5展示了一个格式和缩进都很糟糕的简单 JavaScript文件。即使是这么小的一个文件,它也是难以阅读的,而且每次修改这个文件的时候都可能会产生错误。图2-6展示了使用组合键Ctrl +Shift+F调用JavaScript编辑器的格式化功能后的相同文件。

图2-5  格式糟糕的JavaScript难以阅读和维护

对于使用NetBeans开发Java应用的开发人员来说,NetBeans JavaScript Editor插件是一个很方便的工具。该插件安装简便,功能强大。一旦对JavaScript编辑的支持成为标准NetBeans发行版本的一部分,NetBeans对JavaScript开发的支持一定会得到完善。

图2-6  格式良好的JavaScript,这是使用NetBeans JavaScript Editor格式化的JavaScript调试工具

一直以来,Java开发过程的进步与其调试架构是分不开的,这种调试架构使在源代码中一步一步地调试程序变得非常简单。当今的很多Java IDE都具有异常强大的调试环境,它们允许你调试标准的Java SE应用、部署到本地Java EE应用服务器上的应用,甚至是部署到远程Java EE服务器上的应用。

调试传统的JavaScript要比Java困难得多,因为JavaScript缺少一个高质量的调试环境。这一缺陷现在得到了改善。作为基于Mozilla的浏览器(如Firefox)的扩展,Venkman JavaScript调试器提供了一个功能完整的JavaScript调试环境。

下面我们将简单介绍Venkman及其功能。可以在www.svendtofte.com/code/learning_venkman上找到一份更全面的教程。

使用Venkman

可以从www.mozilla.org/projects/venkman/获得Venkman。Venkman的开发始于2001年4月,由Robert Ginda发起。Venkman基于Mozilla的名为js/jsd的JavaScript调试API。js/jsd API构成了Netscape JavaScript调试器的基础,后者可以用在Netscape浏览器的4.x系列版本中。

在安装好Venkman之后,可以通过Firefox中的Tools→JavaScript Debugger菜单项启动它。图2-17展示了Venkman的默认布局。

Venkman提供了非常多的信息,这些信息分别显示在8个窗格中。默认布局中有一个较大的窗格用来显示选中的源代码。窗口的左边垂直排列着三个较小的窗格。在Source Code窗格下方是Venkman的命令行界面,它位于窗口的底部。

可以用鼠标拖动每个窗口并把它们放置到主窗口的任意位置。还可以把一个窗格添加为另一个现有窗格的独立标签页。例如,根据图2-17,如果想要把Loaded Scripts标签页放置到Local Variables窗格中,只需把Loaded Scripts标签页拖放至Local Variables标签页即可。也可以把窗格从主窗口中分离出来,只需单击窗格标题栏左侧的控制按钮即可。再次单击该控制按钮就可以使窗格回到主窗口中。

图2-17  Venkman的默认窗口布局

在使用Venkman的过程中,你会根据自己的需要经常使用几个面板。单击窗格标题栏右侧的×按钮可以关闭不常用的窗格。可以通过选择View→Show/Hide来重新打开这些窗格。如果想恢复窗格布局的默认设置,只需在Interactive Session窗格中的命令行界面中输入/restore-layout factory即可。

1. 查看已加载的脚本

启动Venkman后,它会识别浏览器窗口中当前页面上所有可用的JavaScript。Venkman可以识别出在HTML页面中使用<script>标签嵌入的JavaScript以及使用<script >标签引入的外部JavaScript文件。

Venkman把当前可用的JavaScript显示在Loaded Scripts窗格中。单击每个文件边上的加号可以打开一个文件内部信息列表,它详细列出了文件中所有可用的JavaScript函数以及这些函数出现在文件中的行号。另外,它还可以显示函数所包含的代码行号。在Loaded Scripts窗格中双击一个函数会在Source Code窗格中显示该文件并直接滚动到该函数所在的位置。

右键单击Loaded Scripts窗格中的文件会为文件本身和文件中的JavaScript函数显示出一些选项。对文件来说,这个右键菜单允许你执行如下一些操作,比如禁止调试eval和timeout声明,禁止调试函数,以及禁止对函数进行性能监控。对单个函数来说,这个右键菜单提供了禁止调试和禁止性能分析的功能。

2. 源代码

Source Code窗格会列出当前文件的源代码。文件的类型可以是HTML、XHTML或JavaScript。Source Code窗格实现了标签页机制,因此可以一次打开多个文件,每个文件都显示在自己的标签页中。Venkman会使用一些简单的颜色显示代码,这样可以提高可读性。JavaScript关键字如function和var会显示为粗体,字符串则会显示为不同的颜色。窗格左侧是文件的代码行编号,再左侧是用于设置断点的侧边栏。

3. 断点

Venkman支持两种断点:硬(hard)断点和将来(future)断点。这与绝大多数调试环境都不太一样,因此我们会讨论这两种断点间的区别。

硬断点就是你经常在像Java这样的现代编程语言中使用的断点。它会指示Venkman在断点处挂起程序的执行。在收到用户的指示之前,程序不能继续执行。在Venkman中,硬断点总是设置在函数体内。

将来断点与硬断点类似,它也指示Venkman在断点处挂起JavaScript的执行。两者的不同之处在于,将来断点总是设置在函数体外。这些代码会在浏览器加载它们之后立即执行。相反,函数体中的代码则一直到该函数响应用户的操作或事件时才会执行。

在很大程度上,大可不必在意硬断点和将来断点之间的区别。在大部分情况下,都会使用硬断点,它们应该与其他调试环境中的断点具有相同的功能。

Venkman提供了一个列出所有当前断点的窗口。当你调试的页面在多个文件中含有多个断点的时候,这就会非常方便。所有设置了断点的文件都会显示在Breakpoints窗格中,在每个文件下面会列出这个文件的所有断点。

4. 分步执行代码

设置好断点之后,就可以开始调试代码了。Venkman会在遇到断点时自动挂起程序的执行。那时,就可以控制脚本的执行了。你可以查看变量值,修改变量值,并继续执行脚本,可以分步执行代码或重新启动并完成执行过程。

在遇到断点时,Venkman为开发人员提供了几个用来分步执行代码的选择。一旦遇到断点,可以选择Continue、Step Over、Step Into或Step Out。

Continue选项会重新启动脚本的执行。执行过程会一直继续,直到遇到另一个断点或脚本结束。当需要跟踪一个问题的位置时,Continue属性非常有用。你可以沿着程序执行链设置多个断点,并且在每次遇到断点的时候查看变量值以确定问题是否已经出现。一旦问题出现了,就可以知道这个问题是出现在当前断点和前一个断点之间,这样就可以从那里继续缩小错误出现的区域。Continue选项还可以用来调试迭代。可以在迭代的某处设置断点并使用Continue选项一次一次地执行迭代代码,并在每次挂起的时候检查是否出现任何问题。

Step Over功能可以使你避免进入当前函数调用的函数。那个被调用的函数可能已经被调试过了并且你知道问题不在那儿,或者你就是不想进入那个函数的代码,因为你只关心当前函数。需要记住的是,越过一个函数并不会影响这个函数的执行;它只是表示你不打算一行一行地调试该函数。

Step Into选项和Step Over功能正好相反。Step Into会进入一个被调用的函数,这样就可以调试这个被调用的函数了。合理使用Step Over和Step Into可以帮助你确定错误的具体位置。

5. 局部变量列表

Local Variables窗格允许你在脚本运行时查看甚至修改变量的值。每当遇到断点并挂起脚本执行时,Local Variables窗格就会显示当前作用域内的所有变量。

Local Variables窗格具有两个顶级项:Scope和This。Scope指向程序执行的当前最近作用域内的所有变量。因为大多数JavaScript都会被编写为函数,所以这个最近作用域往往是函数作用域。例如,如果遇到了一个函数内的断点,那么Local Variables窗格中的Scope项就会指向该函数作用域内的所有变量——也就是在该函数中使用关键字var定义的任何变量。从技术上来说,函数可以访问那些定义在全局作用域内的变量(定义在函数体外的变量),但是它们不会显示在当前变量作用域中。

Local Variables窗格中显示的第二个顶级项是This项。This项指向关键字this指代的任何对象。如果在一个函数中遇到断点,而这个函数又是一个对象的一部分,那么this指代的就是当前对象的实例。正常情况下,this引用的是浏览器的window对象。需要注意的是,在全局作用域内定义的任何变量都会出现在This项下面。

局部变量列表还允许在运行时修改变量的值。这一功能非常强大,它可以帮助你测试不同变量值对脚本输出的影响。当你觉得自己发现了一个问题的时候,还可以使用这一功能修改变量的值,看看是否可以解决这个问题。

右键单击想要修改的变量值,在右键菜单中选择Change Value。这会打开一个提示窗口,可以在里面修改变量的值。可以在提示窗口中输入任何合法的JavaScript表达式,包括new Object()这样的表达式。确保所有的字符串都加上了双引号或单引号。记住,在提示窗口中还可以通过变量名引用其他变量。

2.7  测试工具

作为 Java开发人员,你几乎肯定熟悉测试驱动开发(TDD)这样的开发方法学和JUnit这样的单元测试工具,并且你可能已经在日常的开发过程中使用了这些技术和工具。如果你使用JUnit,那么你也许有过不止一次这样的经历:一个单元测试发现了一个以前未知的错误,这使你免于受到老板的责骂;或者你可以轻松地重构一个类,因为只要能通过所有的测试,重构就不会破坏任何功能。

如果能对 JavaScript(更确切地讲是对Ajax开发)应用TDD和其他自动测试技术,岂不是很棒!现在,你真的可以这么做了。新兴的工具每天都在涌现出来,它们允许你开发具有全面测试覆盖的JavaScript和Ajax应用。在本节中,我们将介绍两款测试工具,它们允许你为JavaScript代码和 AjaxWeb应用创建自动化的测试。

2.7.1  JsUnit

2001 年,Edward Hieatt开始“移植”大受欢迎的Java单元测试框架JUnit(www.junit.org),目的是在浏览器中测试JavaScript。从那以后,JsUnit(www.jsunit.net)的下载次数超过10000次,并且有将近300人加入了它的新闻组。JsUnit支持xUnit通用功能并且全部使用JavaScript编写。如果你习惯使用JUnit(或类似的xUnit框架),就会发现JsUnit十分容易上手。

JsUnit 具有JUnit中的所有主要概念:setUp()和tearDown(),虽然它们现在是函数而不是方法;测试函数(而不是测试方法)被分配到多个测试页面(而不是测试用例)中;并且JsUnit具有它自己的基于HTML的测试运行工具。表2-1对这两个框架进行了比较。

表2-1  Junit与JsUnit的比较

 

JUnitJsUnit
Test类扩展TestCase测试页面包含jsUnitCore.js
Test方法测试函数
Test类基于HTML的测试页面
TestSuite类基于HTML的测试集
各种测试运行工具基于HTML/JavaScript的测试运行工具
setup()和tearDown()方法setup()和tearDown()函数
在虚拟机中运行在浏览器中运行
用Java编写用JavaScript编写

编写 JsUnit测试与编写JUnit测试十分类似。一个测试用例是一个包含你想测试的JavaScript代码的HTML页面。然后按照你在JUnit中的做法编写测试方法并使用各种断言方法验证预期的输出。和JUnit一样,测试用例可以组合在一起构成测试集。JsUnit的测试运行工具(图2-18)是一个HTML页面,可以使用它在浏览器中执行测试用例和测试集,从而实现快速的“代码—测试”循环周期。

图2-18  JsUnit主页上测试运行工具的例子

本书不会讨论安装及使用JsUnit的细节。JsUnit主页www.jsunit.net上有足够多的例子演示如何使用JsUnit。

2.7.2  Selenium

Selenium 是一款针对Web应用的测试工具,可以在www.openqa.com/selenium上找到它。Selenium完全在浏览器中运行,就像真正的用户一样。它可以在所有主流平台上的所有主流浏览器中运行,其主要目的有两个:浏览器兼容性测试和系统功能测试。因为Selenium可以在所有主流平台上的所有主流浏览器中运行,所以可以使用它检验应用是否可以跨浏览器、跨平台运行。通过创建检验应用功能性和用户可接受性的Selenium回归测试实现系统功能测试。

和JsUnit 一样,Selenium也可以用来测试JavaScript和Ajax请求。两者之间的区别在于:JsUnit更侧重于单元测试,而Selenium更侧重于可接受性测试。正因为这样,JsUnit和Selenium可以互补。JsUnit只能用来对JavaScript代码进行单元测试,而 Selenium除了可以测试Web应用的非JavaScript方面外,还可以在应用级测试JavaScript代码。

Selemium 的测试用例是一个含有表格的简单HTML文件,该表格共有三列。这三列分别代表命令(command)、目标(target)和值(value)。并不是所有的命令都必须有一个值,也就是说代表值的表格单元可以为空。因为测试用例是简单的HTML文件,而不是JsUnit中的JavaScript函数,所以非技术人员也可以创建测试用例。

命令仅仅告诉Selenium执行一些操作。命令的类型有两种:动作和断言。动作泛指改变应用状态的行为,如“单击这个按钮”或“在一个文本框中输入文本字段”。断言则会验证应用的状态。断言的例子包括“验证这个文本出现在页面上”或“当前的 URL是这样”。所有的断言都有两种模式可以选择:断言(assert)和验证(verify)。它们几乎一模一样,只是当断言失败时,测试会停止。表2 -2列出了一些最常用的命令。如果需要完整的命令列表,请访问 Selenium的主页。

表2-2  常用的Selenium动作和断言命令

 

命    令描    述
open(url)打开指定的URL;可接受相对URL和绝对URL
click(element)单击一个按钮、链接、单选按钮或复选框
clickAndWait(element)和click一样,但是会等待在单击的响应中加载的新页面;一般用于链接和提交按钮
type(element, value)设置文本框的值,就像用户输入一样
pause(interval)等待指定的毫秒数;有助于测试Ajax请求
assertValue(element, pattern)断言文本框的值是否与指定的模式相符
verifyTextPresent(text)检验指定的文本是否在页面的某处出现

目标是指定命令将要操作的DOM对象。所有命令都必须有一个指定目标。如果指定了一个 clickAndWait命令,那么必须指定该单击操作的目标对象——可能是一个按钮或链接。Selenium支持好几种指定目标的策略。最常用也最简单的就是指定DOM对象的id属性。Selenium还可以通过搜索对象的 name属性、计算给出的JavaScript或XPath表达式或指定链接文本这些方式定位DOM对象。

和JUnit一样,Selenium的测试用例会被打包成测试集。和测试用例一样,测试集也是含有表格的简单HTML页面。测试集的表格由很多行组成,每一行只有一列。每个表格单元都包含一个锚标签,后者用href属性指向测试用例并用文本加以描述。

我们通过Selenium的测试运行工具页面执行测试集。该测试运行工具是一个网页,测试会在该网页中运行并把测试结果显示在网页中。默认情况下,Selenium会在一个默认路径下寻找测试集,当然,这是可以修改的。

1. 测试实例

一旦Selenium能够运行,那么使用起来就会非常简单,但是安装Selenium并编写第一个测试却有那么一点点儿麻烦。在本节中,我们将演示如何在一个Java EEWeb应用中安装Selenium并编写一些简单的测试。

首先下载最新版本的Selenium。下载Selenium会得到一个ZIP文件,其中包含了Selenium运行时引擎和文档。把Selenium下载文件中的 selenium目录复制到应用的WAR文件的根目录下,这样就为你的Java EE应用安装好了Selenium。下面,需要编写一些测试。

在编写Ajax测试之前,我们先尝试测试一个“普通的”HTTP请求。这个例子模拟了一个Web应用的登录过程。用户输入登录ID并单击Login按钮。下一个页面会显示出该登录ID。图2-19展示了本实例的登录页面和显示登录ID的页面。

图2-19  登录页面(左)和显示登录ID的页面(右)

代码清单2-6展示了登录页面的源代码,代码清单2-7展示了登录后页面的源代码。

代码清单2-6  login.jsp

代码清单2-7  loggedIn.jsp

这是一个非常简单的例子,但是它举例说明了如何编写简单的Selenium测试。该测试会模拟用户在文本框中输入一个用户ID然后单击Login按钮。随后的页面应该显示出这个用户ID以及说明登录成功的文本。

代码清单 2-8列出了执行该测试场景的HTML页面的源代码。就像之前解释过的那样,测试被写为一个含有表格的HTML页面,表格由三列组成。本测试共有4个任务:打开登录页面、在文本框中输入文本、单击Login按钮,以及检验随后的页面包含输入的登录ID。每个任务都在表格中占据一行,但是请注意:页面中的表格共有5行,这是因为Selenium会忽略第一行,这主要是考虑到可以使用第一行作为测试用例的名字。

代码清单2-8  testLogin.html

这些命令都是自解释的。open命令指示Selenium在浏览器中访问登录页面。type命令指示Selenium在id属性值为loginButton的 DOM元素中输入文本tsryana。下一个命令clickAndWait会单击id属性值为loginButton的DOM元素并等待随后的页面。最后,verifyTextPresent断言检验本应用是否会正确显示登录页面文本框中输入的用户ID。

完成了!仅仅是编写了这么一个简单的HTML文件,我们就创建了一个能够在多个平台上的多个浏览器中重复运行的测试用例。在使用Selenium的测试运行工具运行这个测试之前,我们将编写第二个测试,这一次我们要测试一个简单的Ajax功能。

这个Ajax实例从服务器获取一行文本并把它显示在页面上。Selenium将检验从服务器获取的文本是否会显示在页面上,即检验Ajax请求的顺利完成。图2-20分别展示了Ajax请求前后的页面。

图2-20  通过Ajax获取简单文本

代码清单2-9列出了该JSP页面的源代码,包括处理Ajax请求的JavaScript代码,你现在应该已经对这些代码很熟悉了。代码清单2-10是响应Ajax请求的JSP。

代码清单2-9  testAjax.jsp

代码清单2-10  ajaxResponse.jsp

和第一个例子一样,这次的测试用例也是一个含有表格的HTML页面,表格共有三列,如代码清单2-11所示。该测试用例由4个任务组成。第一个是open任务,它会令浏览器访问指定的页面。第二个任务click会单击id属性为button的 DOM元素。请注意,这一点与上一个例子中的clickAndWait任务不同;这一次,click任务不会等待新页面的加载。

与一般的 HTTP请求不同,Ajax请求的异步特性意味着并不会加载新的页面。相反,执行Ajax请求的JavaScript会继续运行而不等待Ajax请求的结束。因此,Selenium不能使用clickAndWait任务,因为并不会加载新的页面。在开始执行单击网页中按钮的click任务之后,可以使用 Selenium的pause命令等待一段指定的时间,使Ajax请求在这段时间内完成。在本例中,我们把暂停时间设置为2000毫秒。

最后,verifyTextPresent断言检查Ajax请求的服务器响应中返回的文本是否显示在页面上。代码清单2-11是该测试用例的完整HTML源代码。

代码清单2-11  testAjax.html

创建好以上两个测试用例之后,我们现在该看看如何运行这些测试了。首先,我们必须要创建一个测试集来包含这两个测试用例。正如之前提到的那样,测试集也是一个包含表格的HTML文件,只是它的表格会列出每一个测试用例。代码清单2-12列出了该测试集的源代码。

代码清单2-12  TestSuite.html

现在就可以运行测试了。记住,应该把Selenium运行时文件放在应用的WAR文件的根目录下。部署应用并在浏览器中访问$application- root/selenium/TestRunner.html。默认情况下,Selenium会在selenium/tests目录中寻找测试集。也可以在URL后面添加查询参数?test=path-to- test-suite来访问你的测试集。其中,测试集的路径基于selenium目录的相对路径。

Test Runner页面会打开并列出测试集下的所有测试。可以选择运行全部测试或单个测试。Selenium使用我们熟悉的JUnit颜色指明测试的结果:绿色代表成功,红色代表失败。图2-21显示了之前编写的两个测试的执行结果。

图2-21  运行过两个成功的测试后的Selenium Functional

图2-21 说明这两个测试都通过了,包括Ajax测试用例。如果为Ajax请求编写的测试用例失败了,务必要检查pause命令设置的等待时间是否充足。有些情况下,Ajax请求在头几次执行时速度会比较慢,尤其是存在需要编译的JSP时。另请注意一下图2-21中浏览器的地址栏。它使用一个查询字符串令浏览器访问代码清单2-12所示的测试集。该测试集位于应用根目录下的tests目录中,因为Selenium基于selenium目录执行相对路径搜索,所以这里使用的查询字符串是?test=../tests/TestSuite.html。

2. Selenium IDE

你现在已经看到了,Selenium不仅功能强大,而且简单易用。幸运的是,有另外一种创建Selenium测试的方法甚至比编写简单的HTML文件更加容易,它就是Selenium IDE。

就像其主页www.openqa.org/selenium-ide上描述的那样,Selenium IDE用来编写并执行Selenium测试的集成开发环境。Selenium IDE被实现为一个Firefox扩展,它包含了完整的Selenium核心程序,所以可以直接从IDE记录并播放脚本。Selenium IDE不仅会自动记录脚本,而且允许你手动创建并编辑脚本。它甚至还支持常用Selenium命令的自动完成。

安装 Selenium IDE十分简单,只需在浏览器中访问安装页面www.openqa.org/selenium-ide/ download.action并单击上面的链接,就可以开始安装了。Firefox也许会警告说当前页面正想要安装一个扩展,如果是这样,你就需要授予该网站安装权限。再次单击下载链接,Firefox会打开一个窗口让你确认是否要安装该扩展。单击Install就可以开始下载扩展了。为了完成 Selenium IDE的安装,必须重新启动Firefox。

重新启动Firefox之后,你就可以通过选择Tools菜单下的Selenium IDE菜单项打开Selenium IDE。图2-22展示了Selenium IDE的主窗口。

图2-22  Selenium IDE主窗口

Selenium IDE窗口中的主要部分是Editor选项卡。Editor会列出当前打开的Selenium测试中的所有命令。在这里,可以通过填写Command、 Target和Value的值添加或编辑命令。如果愿意的话,还可以选择Source选项卡直接编辑HTML源代码。

选择 File菜单下的Open命令并导航至代表Selenium测试的HTML文件,就可以打开一个现有的测试。Selenium IDE会加载该测试并在Editor窗格中列出测试中的所有命令。所有命令都可以被编辑、移动、复制或删除,并且可以在测试的任何一点插入新的命令。右键单击Editor窗格中的命令可以列出所有可用的任务。

Selenium IDE会在窗口打开后自动开始记录浏览器的活动。可以单击Editor窗格上方的toolbar右侧的红色圆圈来触发IDE的记录行为。

基本内容就说这么多——让我们开始实际操作吧!我们将给出一个简短的例子来演示用Selenium IDE编写测试是多么的方便。这个例子会复制之前曾演示的Ajax测试,其Selenium测试文件是testAjax.html,如代码清单2-11所示。唯一不同的是,我们将使用Selenium IDE帮助我们编写测试,而不是手动编写HTML文件。

首先,请确保Web服务器正在运行,这样才能正确地测试页面。打开Firefox并访问testAjax.jsp。然后打开Selenium IDE。

现在,Selenium IDE的窗口是空的,回到浏览器窗口中并单击页面中的按钮。Selenium IDE会自动检测按钮的单击事件并填入一些命令,如图2-23所示。

图2-23  Selenium IDE会自动检测按钮的单击并向测试添加命令

可以看到,Selenium自动添加了open命令并把它指向testAjax.jsp文件。还需要注意的是,Selenium在窗口顶部列出了与应用上下文无关的Base URL。如果想测试不同领域(domain)中的应用,如开发(development)领域和预生产(preproduction)领域,这就非常有用了。

既然 Selenium IDE已经为我们创建了open和click命令,那么我们只需要添加verifyTextPresent命令就可以使当前测试与代码清单2-11中的测试相一致了,这个命令会检验Ajax调用是否成功以及响应文本是否被添加到页面中。单击click命令下面的区域,被单击的表行应该会突出显示,这时你就可以在它们各自的输入框中输入verifyTextPresent命令以及想要检验的文本了。确保在Value输入框中输入想要检验的文本。注意,随着你开始在输入框中键入verifyTextPresent,在一个下拉列表中会显示所有匹配的命令,允许你选择想使用的命令,从而最小化了键入量并降低了出错的机会。

可以单击Source选项卡检验命令是否正确地添加到了测试的HTML文件中。现在,Source选项卡中的内容应该与代码清单2-11几乎一模一样。

创建好测试内容后,需要做的就只是运行测试了。Selenium IDE提供了两种运行测试的方法。第一种是在浏览器窗口中运行测试,这与本章之前的做法相同。想要使用这种方法,可以单击Selenium IDE窗口右侧邻近红色Record按钮的绿色箭头。这将在Firefox中打开一个指向Selenium Test Runner的浏览器窗口,可以从这里启动测试。

另一种方法是直接在Selenium IDE中运行测试。想要使用这种方法,可以单击最左侧的绿色箭头,测试就会执行,并且通过了的命令会突出显示为绿色,未通过的命令则会突出显示为红色。图2-24展示了成功的测试。

图2-24  Selenium IDE中执行的成功测试

使用Selenium IDE,我们不编写任何HTML就可以创建并执行一个Selenium测试。事实上,唯一需要键入的就是verifyTextPresent命令,并且自动完成功能还会帮助我们完成命令的键入。Selenium IDE最好的地方就在于它足够简单,即使非技术人员,如项目经理或企业主,也可以使用它。

如果你正在使用Selenium,那么你就应该考虑使用Selenium IDE,因为它提供了比手动编写测试多得多的好处。你可以在它主页上找到更多关于如何使用它的信息。在http://wiki.openqa.org/ display/SIDE/Recording+a+Test上可以找到一段演示如何记录测试的视频。

3. 我该使用哪款测试工具

就其本质而言,JsUnit和Selenium都是非常强大的工具。对于那些非常熟悉 JUnit的开发人员来说,JsUnit可能是最自然的选择。 Selenium与JsUnit的不同之处在于:Selenium测试的是应用的功能性(而不是测试一个个JavaScript函数)及其编写测试用例的方式。Selenium把测试用例编写为HTML表格而不是JavaScript,即使这样,我们还可以使用Selenium IDE自动记录并编辑测试。

我们应该真正明白的是,这两款工具之间更多的是一种互补的关系。作为测试工具, Selenium更关注于用户接受或集成测试,并且其编写测试用例的方式意味着非技术人员也可以编写测试用例。综合使用Selenium和更“传统的”单元测试工具(如JsUnit)可以提供非常强大的测试架构。

2.8  小结

在本章中,我们介绍了几款能够简化Ajax开发的工具。JSEclipse这样的JavaScript编辑器通过诸如语法突出显示和代码完成这样的功能使编写大量JavaScript变得简单,而格式化工具则可以帮助我们处理格式糟糕的遗留JavaScript文件。

Dojo JavaScript压缩器可以压缩你的JavaScript文件,减少它们消耗的带宽,并在压缩的过程中提供一些混淆功能,它甚至可以集成到Ant构建过程中。Mouseover DOM Inspector是一款响应迅速、简单易用的工具,它可以帮助你了解HTML文档的结构,这对掌握HTML页面信息和调试有很大帮助。

NetBeans 的HTTP Monitor能够帮助你跟踪程序中的臭虫,它会为你准确地显示出浏览器如何发送请求以及请求中含有什么参数(如果有的话)。Venkman是一款非常强大的JavaScript调试环境,它提供了一次执行一行JavaScript代码的能力。JavaScript日志框架(如Log4JS或 Lumberjack)为你的JavaScript代码带来了log4j式的日志功能。

最后,JsUnit和Selenium这样的工具使得所有测试优先和单元测试开发技术都可以在JavaScript开发中使用。这两个都是非常棒的工具,它们为JavaScript和Web开发带来了可重复测试用例的概念。

这些工具和将来不断涌现出的工具会帮助你在更短的时间内花更少的力气开发出质量更高的Ajax应用。尝试使用它们,看看如何能把它们集成到你的开发过程中。

 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值