我去了链接后的页面对象模式,概念很好,
https://code.google.com/p/selenium/wiki/PageObjects
这是我的疑问:
public LoginPage typeUsername(String username) {
driver.findElement(usernameLocator).sendKeys(username);
return this;
}
public LoginPage typePassword(String password) {
driver.findElement(passwordLocator).sendKeys(password);
return this;
}
public HomePage submitLogin() {
driver.findElement(loginButtonLocator).submit();
return new HomePage(driver);
}
上面的selenium调用包含了一些函数,我们在testcase或任何页面级函数中调用这些函数,如下所示:
public HomePage loginAs(String username, String password) {
typeUsername(username);
typePassword(password);
return submitLogin();
}
我的疑问是:为什么我们不能直接调用sendkey或在整个项目中每次提交或点击。只有一行代码我们用自己的函数包装,这将花费更多的时间来运行代码。
是否有任何性能问题?
答案 0 :(得分:1)
恕我直言,关键的好处是页面对象和测试是独立发展的。如果有结构更改,您不会更改测试,反之亦然,如果您想要更改您正在测试的内容,则无需更改页面对象。将试图在一个例子中说明这一点
考虑在不遵守页面对象模式的情况下编写的测试,例如:测试产品细节。
this.driver(Find.By.id("username")).sendKeys(username);
this.driver(Find.By.id("pass")).sendKeys(password);
this.driver(Find.By.id("submit")).click();
// navigate to product listing page
this.driver(Find.By.id("product-usb")).click();
// navigate to product details page
this.driver(Find.By.id("product-a")).click();
assert(this and that);
在此示例中,如果发生结构更改(主要重新设计),您将强制更改测试。 现在,您预计会发生变化,首先,您要确保没有代码重复,这样您才能在时间正确的情况下在一个地方进行更改。您在方法中拆分代码,最合理的拆分基于逻辑单元,而断言保留在它们所属的测试中
login(username, password);
moveToProductListing();
selectProduct(productID);
assert(this and that);
问题在于应该实现这些方法,以便您可以在测试中轻松访问它们。如果它是一个实用程序类,它将很快变得臃肿。进一步思考将引导您按页面对象进行分组。
你的测试最终不知道被测试页面的结构(它隐藏在页面对象中),以及页面对象对你正在进行的测试特定断言一无所知。
答案 1 :(得分:1)
因为您已经开始使用Selenium文档了。如果你看看这些Test design considerations,我认为这也会有所帮助。作为@Master Slave回答的补充,你会看到
包装Selenium电话
与任何编程一样,您将需要使用 实用程序函数来处理否则将被复制的代码 在整个测试中。防止这种情况的一种方法是经常包装 使用了您自己的函数或类方法的selenium调用 设计。
并使用WebElements Presence的“安全操作”进行扩展。
关于Page对象,很高兴阅读PageFactory的提示。
答案 2 :(得分:0)
我认为这个问题和你的怀疑是围绕着基本的,更多的是我会尝试回答
究竟什么是Page Object设计模式?
嗯,页面对象是您系统中的页面(或视图)的某种API,让我们将其视为页面为测试人员提供的“服务”......
一旦被视为如此,我相信更容易想到动机......
页面对象知道其匹配的HTML页面(或视图)的内部,它只知道它......
例如,如果我们想要执行登录(作为用户),我们将为您提供以下服务:
当然还有更多的“服务”,但我们可以在这里停下来回到这一点......我们应该对这些“服务”做些什么?这很简单:
我们需要创建一个“LoginPage”对象,它知道页面的(私有)选择器和HTML构造(id,类,xpath等等)。测试人员的公开内容是什么?我们刚才谈到的服务......
测试人员可以向登录页面询问“TypeUsername(string inputUsername)”或TypePassword(string inputPassword) - 如果您使用此页面测试其他页面,您还可以添加“LoginAsDefaultUser()”之类的“服务”... < / p>
问题
虽然这是一个良好的开端,但仍有很大的改进空间。
最明显的问题是,我们可能需要跨多个页面对象执行常见操作。使用我们当前的方法,我们最终会得到重复的代码。
解决方案
当创建包装Selenium核心的BasePage对象,并且每个页面从该页面继承(直接或直接)时,我们正在创建一个未耦合的动态环境,如果某个页面(或视图)发生了变化,则需要只修复一个特定对象。
<强>摘要强>
<强>动机强>