Selenium 和 TestNG
TestNG 以其灵活性和参数化 fixture 成为定义 Selenium 的驱动验收测试的首选。TestNG 能够定义测试依赖项并返回失败的测试,以及其易用性,使得 Selenium-TestNG 成为吸引人的组合。
让我们首先从一个能够允许用户创建、查找、更新或删除小部件的 Web 应用程序开始。创建一个小部件需要三个属性:名称、类型和定义。图 1 显示了创建小部件的表单:
图 1. 创建小部件的 Web 表单
请注意:表单元素的类型是具有三个不同选项的下拉列表,如图 2 所示:
图 2. 包含下拉列表的 Web 表单
单击 Create Widget 将促使 Groovlet 处理这一请求。如果所有内容正确的话(即名字和定义不为空,并且数据库中不存在该实例),Groovlet 将创建一个新的小部件实例并类似图 3 所示的状态页面:
图 3. 返回的 Web 页面显示状态
结合使用 Selenium 和 TestNG 验证简单的 Create Widget 用例是一种可管理的应用:
配置并启动 Selenium 服务器的实例。
与 Create Widget Web 表单交互并提交它。
检验结果页面是否包含具有小部件名称的成功信息。
停止 Selenium 服务器实例。
请注意:用例中的每一步都是通过 Selenium 完成的 —— 所以说,TestNG 仅仅帮助进行查找。现在,我们来实践一下。
Create Widget 测试用例
我希望对 Selenium 服务器进行灵活的配置,所以我将编写一个参数化 fixture(TestNG-Selenium 样式),一般可以使用它来为不同浏览器、不同位置甚至混合的 Web 应用程序地址(类似 localhost 和产品)创建 Selenium 服务器。清单 4 定义了我所配置的灵活的 Selenium 服务器 fixture:
清单 4. 灵活的 Selenium fixture
@Parameters({"selen-svr-addr","brwsr-path","aut-addr"})
@BeforeClass
private void init(String selenSrvrAddr, String bpath,
String appPath) throws Exception {
driver = new DefaultSelenium(selenSrvrAddr,
SeleniumServer.getDefaultPort(), bpath, appPath);
driver.start();
}
//....
@AfterClass
private void stop() throws Exception {
driver.stop();
}
必须将参数名与 TestNG 的 testng.xml 文件中的值链接起来;因此,我定义了如清单 5 所示的三个参数。(默认情况下为 Firefox 定义了 brwsr-path 参数,但是我可以同样轻松地定义一组新的使用 Internet Explorer 的测试。)
清单 5. TestNG testng.xml 文件中的参数值
接下来,我将定义清单 6 所示的测试用例,它也包含一个参数,用于进行测试的应用程序的基 URL。该测试将促使浏览器在 Web 应用程序内打开特定页面,并操作 图 1 所示的表单。
清单 6. 一个良好的测试用例
@Parameters({"aut-addr"})
@Test
public void verifyCreate(String appPath) throws Exception {
driver.open(appPath + "/CreateWidget.html");
driver.type("widget", "book-01");
driver.select("type", "book");
driver.type("definition", "book widget type book");
driver.click("submit");
driver.waitForPageToLoad("10000");
assertEquals(driver.getText("success"),
"The widget book-01 was successfully created.",
"test didn't return expected message");
}
通过调用 driver.click("submit") 提交表单后,Selenium 将等待响应的加载,然后我将断言成功的创建信息。(注意:响应 Web 页面具有一个 ID 为 success 的元素。)
结果产生一个灵活的文本类,它将检验两种场景:一种是良好的场景,而另一种是没有提供定义的边界用例,如清单 7 所示:
清单 7. 使用 TestNG 进行全部的处理
public class CreateWidgetUATest {
private Selenium driver;
@Parameters({"selen-svr-addr","brwsr-path","aut-addr"})
@BeforeClass
private void init(String selenSrvrAddr, String bpath,
String appPath) throws Exception {
driver = new DefaultSelenium(selenSrvrAddr,
SeleniumServer.getDefaultPort(), bpath, appPath);
driver.start();
}
@Parameters({"aut-addr"})
@Test
public void verifyCreate(String appPath) throws Exception {
driver.open(appPath + "/CreateWidget.html");
driver.type("widget", "book-01");
driver.select("type", "book");
driver.type("definition", "book widget type book");
driver.click("submit");