使用分层的 Selenium 框架进行复杂 Web 应用的自动测试(2)

发表于:2014-08-07来源:IBM作者:王晨点击数: 标签:selenium
继续上文谷歌搜索的场景,通过实例来了解 TestNG 的用法与功能。 清单 5. TestNG 应用示例 @Parameters( { url, query-string, btn-id, txt-id, verify-String }) @Test public voi

  继续上文谷歌搜索的场景,通过实例来了解 TestNG 的用法与功能。

  清单 5. TestNG 应用示例

  @Parameters( { "url", "query-string", "btn-id", "txt-id", "verify-String" })

  @Test

  public void testGoogle(String url, String queryString, String btnID,

  String txtID, String verifyString) {

  selenium = new DefaultSelenium("localhost", 4444, "*firefox", url);

  selenium.start();

  selenium.open("/");

  selenium.type(txtID, queryString);

  selenium.click(btnID);

  selenium.waitForPageToLoad("30000");

  verifyTrue(selenium.isTextPresent(verifyString));

  selenium.stop();

  }

  上面的代码清单中,注释 Parameters 指定的参数在 TestNG 测试框架的配置文件 testng.xml 里有具体定义,如下所示:

  清单 6. testng.xml 示例

  不难想到,只要修改 testng.xml 中的参数值,就能由输入参数驱动不同的测试用例。然而,仅仅在 testng.xml 中指定参数有很大的局限性,显然过多的参数会难以维护,无法井井有条地组织分属不同 Test Cases 的输入。在下文中,我们来解决这个问题。

  回页首

  基于 Selenium 的分层测试框架

  作者在工作中,测试基于 OSGi 平台的多个插件。每个插件实现特有的功能,有多条测试路径需要覆盖,同时,各个插件之间又有共通之处,可以抽取某些部分进行复用。对此,我们假设这样的场景:分别在谷歌、百度和必应中搜索各种关键字,并在返回的结果页面中验证是否存在目标字符串。每个搜索引擎都可以视为一个待测的组件,分别为它们撰写 Test Cases,并组织成一个 Test Suite,用于执行测试。事实上,3 个搜索引擎的测试由于同质性,还能够合并为一种测试,用不同的输入参数来指定所要测试的那个搜索引擎。这里视为三个组件,只是为了说明如何在 Selenium+TestNG 环境中组织多个测试模块。

  自上而下地考虑,上段描述的测试场景能够进行分解。Test Suite 包含三类 Test Cases(谷歌、百度与必应),每类 Test Cases 的一个 Test Case 由若干可复用的 Test Tasks 组成,通过传入不同的参数,Test Task 完成同质的不同行为。在 Test Task 之下,定义相关文件,包含待测试的 Web 页面元素的定位信息。因此,分层 Selenium 框架有三个层次:

  appObjects —— Web 页面元素定位信息,如按钮与文本框等;

  tasks ——测试步骤中可复用的行为;

  test cases ——由 tasks 组成的测试用例。

  Web 元素 locators 定义与收集

  Selenium 根据 XPath 来定位 Web 元素,XPath 的相关知识不属于本文的内容。前面例子中,在 TestNG 的配置文件 testng.xml 里定义文本框与按钮的 locators,对于复杂的测试场景而言,这不是好的实践。因此,我们在 appObjects 层建立文件,将 Web 页面元素 locators 归入,便于维护使用。Selenium-IDE 的 Find 功能适于完成这一步骤。文件 googlePages.properties 的内容如下:

  清单 7. locators 文件示例

  #define the keys and corresponding XPaht locators of google page.

  googleSearchTxtField=//input[@name='q']

  googleSearchBtn=//input[@name='btnG']

  这时,在 testng.xml 中,删去 locators 相关的 parameters,只需要解析 .properties 文件,生成 locators 的 properties 备用。在所附的源码中可以看到 .properties 文件的解析器 PropUtils 的简单实现。

  测试任务分解与实现

  为说明任务分解,以简单的搜索过程为例,可以分为输入搜索关键字、点击搜索按钮、以及验证结果页面。实际代码如下所示,不难发现,由参数决定行为方式的测试任务,都接受一个 paraMap 数据结构,并根据其内容在方法内采取适当的行为。通过这种方式,test cases 能够以参数配置文件来驱动测试任务实施其想要的行为。

  清单 8. Test Task 代码示例

  public void openSite() {

  selenium.open("/");

  }

  public void typeSearchTxtField(HashMap paraMap) {

  utils.waitForElement((String) elemMap

  .get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD), 30);

  selenium.type((String) paraMap

  .get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD),

  (String) elemMap

  .get(TestGoogleConstants.GOOGLE_SEARCH_TXT_FIELD));

原文转自:http://www.ibm.com/developerworks/cn/java/j-lo-selenium/index.html