Dub*_*Dev 7 automated-tests webdriver pageobjects selenium-webdriver protractor
这是一个我无法找到确切来源的问题,希望基于用户以前的经验获得一些答案,主要是解释为什么某种方法无法解决。
我正在通过Protractor使用webdriver进行自动化,并且正在争论是否应在页面对象本身之外使页面元素可用。经过研究,人们似乎采取了几种不同的方法,但我无法完全掌握每种方法的长期含义。
我已经看到页面对象模型的以下不同实现:
这是我最不喜欢的方法,因为这意味着在测试中实际上已识别出元素。设置这似乎是一个糟糕的标准,因为它可能会鼓励自动化人员直接在应用程序中使用新的定位器,而不是页面对象。同样,在初始化PO时,不能直接设置任何需要动态信息的参数,需要进一步编辑。
pageobject.js
export default class HomePage {
constructor() {
this.passwordField = '#password';
this.usernameField = '#user';
}
}
Run Code Online (Sandbox Code Playgroud)
test.js
const homePage = new HomePage();
$(homePage.usernameField ).sendKeys('admin');
$(homePage.passwordField ).sendKeys('password');
Run Code Online (Sandbox Code Playgroud)
pageobject.js
export default class HomePage {
constructor() {
this.passwordField = $('#password');
this.usernameField = $('#user');
}
}
Run Code Online (Sandbox Code Playgroud)
test.js
const homePage = new HomePage();
homePage.usernameField.sendKeys('admin);
homePage.passwordField.sendKeys('password);
Run Code Online (Sandbox Code Playgroud)
这是我过去使用的方法,最终我们获得了许多功能。例如setUsename(), getCurrentUsername(), getUsernameAttibute(), verifyUsernameExists()
,password
元素和许多其他元素具有和。我们的页面对象变得巨大,所以我觉得这不再是最好的方法。但是,优点之一是我们的测试看起来很干净而且可读性很强。
pageobject.js
export default class HomePage {
constructor() {
var passwordField= $('#password');
var usernameField = $('#user');
}
setUserName(name){
username.sendKeys(name);
};
setPassword(password){
passwordField.sendKeys(password);
};
}
Run Code Online (Sandbox Code Playgroud)
test.js
const homePage = new HomePage();
homePage.setUsername('admin');
homePage.setPassword('123');
Run Code Online (Sandbox Code Playgroud)
我很想获得对此的一些反馈,因此希望您可以花些时间阅读。
我更喜欢并相信最后一种方法是最好的。
撇开我们谈论自动化的事实不谈,任何好的/伟大的软件都具有以下特征。
最后一种方法提供了您指出的测试清洁度的额外好处。
然而,大多数时候,无论出于何种原因,我们都倾向于忽略模块化并让现有的 PO 变得臃肿。这是我见过的并且是其中的一部分。因此,在某种程度上,PO 变得臃肿并不是因为方法,而是因为自动化人员/测试人员/开发人员有意识地保持 PO 模块化、组合和简单的方式。无论是关于 PO 还是应用程序功能代码都是如此
划船 PO:
具体到PO臃肿的问题,看看能不能把PO中的公共元素分出来。例如。页眉、页脚、左导航、右导航等在页面之间是通用的。它们可以被分离出来,并且 PO 可以由那些单独的部分/部分组成。
即使在主要内容中,如果其合乎逻辑并且可以跨页面重用,将公共内容(如果它跨两个或多个页面,如果不是全部)分离到它们自己的组件 API 中。
自动化规范对 ex 执行广泛的回归是正常的。一个元素是一个密码字段,文本框的长度是某某等等。在这种情况下,为每个规范用例(或期望)添加方法是没有意义的。好消息是,这里的共性也占据了中心位置。基本上,提供跨规范使用的 API,而不是在一个规范中使用的 API。
以ex为例。密码字段应该被屏蔽。您不太可能想在多个规范文件中测试它。在这里,我们可以在LoginPO
like 中为它添加一个方法,isPasswordMasked()
或者我们可以让密码字段可访问,LoginPO
并且规范对密码类型字段进行实际检查。通过这样做,我们仍然让LoginPO
在密码字段信息的控制,可向其他API(事务login()
,logout()
等等),即只有PO知道如何以及在何处获取密码元素。具有将规范测试推送到规范文件的额外优势。
该采购订单expect
/assert
在任何时候,将任何测试(或)作为 PO API 的一部分都不是一个好主意expect
。原因:
FWIW,我还没有遇到任何要求使用臃肿 API 的网页。
暴露 PO 中的元素:
这取决于我相信的用例。可能是仅在一个规范中使用的元素可以是要公开的基本情况。也就是说,一般来说,这个想法是规范应该对测试人员/开发人员以及以后查看它们的人来说是可读的。无论是使用有意义的元素变量名称还是方法名称完成,充其量只是一种偏好。另一方面,如果一个元素意味着有一些涉及交互(例如悬停打开菜单链接),它绝对是单独通过 API 公开的候选者。
希望增加一些澄清!
最后一种方式是实现页面对象的正确方式。页面对象背后的想法是它隐藏了页面的内部结构,并为脚本调用提供了一个干净的 API,以在页面上执行操作。定位器和元素不应暴露。您需要对页面执行的任何操作都应该通过公共方法公开。
避免页面上每个字段都使用 getter 和 setter 的一种方法是合并方法。考虑用户将在页面上执行的操作。与其使用.setUsername()
、.setPassword()
和.clickLoginButton()
方法,您应该只拥有一个login()
将用户名和密码作为参数并完成所有登录工作的方法。
参考
Martin Fowler 通常被认为是“页面对象”概念的发明者,但其他人创造了“页面对象”这个名称。参见他对页面对象的描述。
Selenium 关于页面对象的文档。
归档时间: |
|
查看次数: |
168 次 |
最近记录: |