BDD - SpecFlow Page Object Model POM
创始人
2024-01-25 07:02:23
0

BDD - SpecFlow Page Object Model

  • 引言
  • POM 优势
  • POM 简单实现
  • POM 缓存实现
  • POM 层次实现
    • Parent - Child 关系
    • Component 关系

引言

前面文章《 BDD - SpecFlow Web UI 测试实践 》就运用到 Page Object Model,简称 POM,POM 是一种模式,结合 Selenium 用来抽取 Web UI,使得 UI 自动测试更易实现,今天就来详细介绍一下 POM 。

POM 优势

当运用 Selenium 时,总是用 WebElements 来访问不页面上不同的元素。可以利用 WebDriver 类中的方法 FindElement 和 FindElements 来定位到这些 WebElements。

如果你总是直接在 automation code 里直接使用这些方法,会造成大量的重复代码。这个时候就得考虑用 POM 了,将调用 FindElement(s) 方法隐藏在一个类里。

使用 POM 的好处:

  • 使得这些隐藏 FindElement(s) 方法的类重用
  • 如果 UI Element 有变化,只需修改一个地方
  • 减少 Binding 类对 HTML 结构的依赖

POM 简单实现

HTML:


Code:

public class PageObject
{private IWebDriver _webDriver;public PageObject(IWebDriver webDriver){_webDriver = webDriver;}public IWebElement txtUrl => _webDriver.FindElement(By.Id("txtUrl"));
}

public 构造函数中传入 WebDriver 实例,这个 WebDriver 依赖注入,详情参考 《 BDD - SpecFlow Context Injection 上下文依赖注入 》,当访问 TxtUrl 属性时,WebDriver 将在整个 Page 搜索 id 为 txtUrl 的 Element。注意,这里没有涉及到缓存,也就是说每次访问 TxtUrl 属性时,WebDriver 都会重新搜索一遍。

POM 缓存实现

HTML:


Code:

public class PageObject
{private IWebDriver _webDriver;private Lazy _txtUrl;public PageObject(IWebDriver webDriver){_webDriver = webDriver;_txtUrl = new Lazy(() => _webDriver.FindElement(By.Id("txtUrl")));}public IWebElement txtUrl => _txtUrl.Value;
}

还是在 public 构造函数中传入 WebDriver 实例,进行 WebDriver 依赖注入。只是利用 Lazy 这种简单的方式将 FindElement 方法的结果缓存起来。

只有第一次访问 txtUrl 属性时,才会触发调用 FindElement 方法,后面访问 txtUrl 属性时,只会返回第一次访问时缓存的值。这样有助于节省自动化执行时间,因为 WebDriver 针对同一 Element 只需搜索一次。

注意,如果你使用上面的缓存模式,当心页面和页面元素的生命周期。如果页面有发生变化,不要用老的 Element 对象。

POM 层次实现

Parent - Child 关系

HTML:

Code:

public class ParentPageObject
{private IWebDriver _webDriver;public ParentPageObject(IWebDriver webDriver){_webDriver = webDriver;}public IWebElement WebElement => _webDriver.FindElement(By.ClassName("A"));public ChildPageObject Child => new ChildPageObject(WebElement);
}public class ChildPageObject
{private IWebElement _webElement;private Lazy _txtUrl;public ChildPageObject(IWebElement webElement){_webElement = webElement;}public IWebElement WebElement => _webElement.FindElement(By.ClassName("B"));
}

本例中,我们稍微调整一下 HTML 文档,两个 div 元素有相同的 class 属性 B 值,但是我们只想为具有 class A 属性的 div 元素及其子元素创建 PageObject。

就好比一个或多个页面有相同的元素组件一样,我们可以分层次创建 POM 类。我们可以将元素组件单独创建 POM 类,作为 ParentPageObject 类的 ChildPageObject。

如果我们用相同的 WebDriver.FindElement 方法,我们将得到与 A div在同一层的 div元素。

但是每个 WebElement 都有 FindElement(s) 方法,使得我们可以在整个 HTML 文档的局部范围内定位元素。
所以我们可以通过传 parent- WebElement 到 ChildPageObject 类,只定位 A-div 内部的 B-div。

Component 关系

上面是采用 Parent - Child 层次结构,当然也可以 Component 层次结构,将HTML 文档稍微改一下,div A 和 div B 分别是 component,HomePageObject 分别包含 ComponentAPageObject 和 ComponentBPageObject。

HTML:

Code:

public class HomePageObject
{private IWebDriver _webDriver;public ParentPageObject(IWebDriver webDriver){_webDriver = webDriver;}public ComponentAPageObject componentA => new ComponentAPageObject(_webDriver);public ComponentBPageObject componentB => new ComponentBPageObject(_webDriver);}
public class ComponentAPageObject
{private IWebDriver _webDriver;public ParentPageObject(IWebDriver webDriver){_webDriver = webDriver;}public IWebElement WebElement => _webDriver.FindElement(By.ClassName("A"));
}public class ComponetBPageObject
{private IWebDriver _webDriver;public ParentPageObject(IWebDriver webDriver){_webDriver = webDriver;}public IWebElement WebElement => _webDriver .FindElement(By.ClassName("B"));
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...