test runner 脚本使用与 xUnit 框架相同的测试套件(test suite)和测试用例概念。测试用例和命令按照它们在测试套件和测试用例中出现的顺序依次执行。在 清单 1 中:
* 第一列包含命令 或断言。
* 第二列包含命令或断言的目标(target)。这里可以用多种受支持的组件定位符中的一种来指定目标。通常使用的是组件的 ID 或名称,但 XPath 和 DOM 定位符也是受支持的。
* 第三列包含用于为命令或断言指定参数的值。例如,当使用 type 命令时,这一列可能是一个文本域所期望的值。
即使对于非技术人员来说,test runner 脚本也易于阅读和编写。当在一个浏览器中打开 清单 1 中的例子时,将得到类似这样的一个表:
First command Target Value
Second command Target Value
接下来,我将描述如何使用命令和断言编写一个简单但是完整的测试用例。
测试用例实例
执行 清单 2 中的测试脚本时,它将执行以下操作:
1. 通过进入 /change_address_form.html 打开变更地址页面。
2. 在 ID 为 address_field 的文本框中输入 Betelgeuse state prison。
3. 单击名为 Submit 的输入区。注意,这里使用 XPath 找到 Submit 按钮,这导致表单数据被发送到服务器。
4. 验证页面是否包含文本 Address change successful。
清单 2. 在测试用例中使用命令和断言的例子
<table>
<tr>
<td>open</td>
<td>/change_address_form.html</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>address_field</td>
<td>Betelgeuse state prison</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//input[@name='Submit']</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Address change successful</td>
<td></td>
</tr>
</table>
测试套件
要达到对应用程序的完全测试覆盖,通常需要不止一个测试用例。这是 Selenium 使用测试套件的原因。测试套件用于将具有类似功能的一些测试用例编成一组,以便让它们按顺序运行。
测试套件和测试用例一样,都是用简单的 HTML 表编写的。Selenium 执行的缺省测试套件的名称是 TestSuite.html。清单 3 展示了一个测试套件,该套件像通常的用户一样测试应用程序。注意,测试套件使用一个只包含一列的表,表中的每一行指向一个包含某个测试用例的文件。
清单 3. 测试套件示例
<table>
<tr>
<td>Test suite for the whole application</td>
</tr>
<tr>
<td><a href="test_main_page.html">Access main page</a></td>
</tr>
<tr>
<td><a href="test_login.html">Login to application</a></td>
</tr>
<tr>
<td><a href="test_address_change.html">Change address</a></td>
</tr>
<tr>
<td><a href="test_logout.html">Logout from application</a></td>
</tr>
</table>
接下来我将把目光转移到 driven 测试脚本。
driven 模式
driven Selenium 脚本是用多种受支持的编程语言中的一种编写的 —— 目前可用的有 Java、Ruby 和 Python 驱动程序。这些脚本在浏览器之外的一个单独的进程中运行。驱动程序的任务是执行测试脚本,并通过与运行在浏览器中的 browser bot 进行通信来驱动浏览器。驱动程序与 browser bot 之间的通信使用一种简单的特定于 Selenium 的连接语言 Selenese。
driven 脚本比 test runner 脚本更强大、更灵活,可以将它们与 xUnit 框架集成。driven 脚本的缺点(与 test runner 脚本相比)是,这种脚本编写和部署起来更复杂。这是因为驱动程序必须执行以下任务:
* 启动服务器。
* 部署所测试的应用程序(AUT)。
* 部署测试脚本。
* 启动浏览器。
* 发送命令到 browser bot。
* 验证 browser bot 执行的命令的结果。
driven 脚本更依赖于应用程序运行时环境。例如,Java 驱动程序使用一个嵌入式 Jetty 或 Tomcat 实例来部署所测试的应用程序。目前,已经有人在致力于将 Selenium 集成到 Ruby on Rails 中,但是在我撰写本文之际,这个集成版本还没有被发布。
清单 4 摘自一个使用 Ruby 驱动程序的 driven 测试脚本。注意,我省略了用于启动服务器和浏览器的步骤,这个测试脚本代码几乎和 test runner 脚本一样简单。
清单 4. 使用 Ruby 驱动程序的例子
puts selenium.open('/logout.html')
puts selenium.verify_location('/index.html')
现实中的需求
在接下来的两节(现实中的需求 和 现实中的用例)中,我将描述如何在现实场景中使用 Selenium,并针对用 Ruby on Rails 和一点儿 Ajax 技术编写的一个简单的股票报价查看器应用程序编写 Selenium 测试用例。虽然这个应用程序是用 Ruby on Rails 编写的,但是也可以将这个例子应用于任何 Web 应用程序,因为测试脚本是按 test runner 模式以 HTML 编写的。这个示例应用程序是用 Ruby 1.8.3 和 Ruby on Rails 0.14.2 测试的,但是它也可能可以使用更旧的或更新的版本。
如果有 Linux,那么发行版中通常已经包括了 Ruby。在命令提示符下运行 ruby -v,检查您所拥有的版本。对于大多数平台,都可以在http://www.ruby-lang.org/上找到一个 Ruby 发行版。
接下来的步骤是通过 RubyGems 打包系统安装 Ruby on Rails。为此,只需执行 gem install rails --include-dependencies。在某些平台上,必须执行一些额外的步骤,所以请访问 Ruby on Rails 网站,以获得更多细节。
在我撰写本文之际,目前可用的 Selenium 版本是 0.6。我已经将它集成在示例应用程序中(见 下载 小节),我的做法是从http://selenium.thoughtworks.com/下载 Selenium Core 包,然后将名为 selenium 的文件夹复制到用于静态内容的文件夹。在 Ruby on Rails 应用程序中,这个文件夹的名称是 public。在 J2EE Web 应用程序中,可以将 selenium 文件夹放在 Web 应用程序的根目录或 WAR 归档文件中。
后一步是下载示例应用程序。从 下载 小节中获得这个包。解压应用程序,并打开一个命令提示符。然后转入应用程序被解压到的那个目录。为了启动应用程序,运行 ruby script/server。应该看到 Rails 成功启动了,如 图 1 所示。