Page Objects

原文地址:https://github.com/SeleniumHQ/selenium/wiki/PageObjects

Within your web app's UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place.//Page Object将页面内的元素及操作模型化,目的是减少重复代码和易于修改。

Implementation Notes

PageObjects can be thought of as facing in two directions simultaneously. Facing towards the developer of a test, they represent the services offered by a particular page. Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page (or part of a page) It's simplest to think of the methods on a Page Object as offering the "services" that a page offers rather than exposing the details and mechanics of the page. As an example, think of the inbox of any web-based email system. Amongst the services that it offers are typically the ability to compose a new email, to choose to read a single email, and to list the subject lines of the emails in the inbox. How these are implemented shouldn't matter to the test.//PageObject隐藏页面的细节,只提供页面的功能。

Because we're encouraging the developer of a test to try and think about the services that they're interacting with rather than the implementation, PageObjects should seldom expose the underlying WebDriver instance. To facilitate this, methods on the PageObject should return other PageObjects. This means that we can effectively model the user's journey through our application. It also means that should the way that pages relate to one another change (like when the login page asks the user to change their password the first time they log into a service, when it previously didn't do that) simply changing the appropriate method's signature will cause the tests to fail to compile. Put another way, we can tell which tests would fail without needing to run them when we change the relationship between pages and reflect this in the PageObjects.//PageObject的一个方法应该返回一个页面PageObject。

One consequence of this approach is that it may be necessary to model (for example) both a successful and unsuccessful login, or a click could have a different result depending on the state of the app. When this happens, it is common to have multiple methods on the PageObject://将成功和失败的操作都模型化。

 public class LoginPage {
public HomePage loginAs(String username, String password) {
// ... clever magic happens here
} public LoginPage loginAsExpectingError(String username, String password) {
// ... failed login here, maybe because one or both of the username and password are wrong
} public String getErrorMessage() {
// So we can verify that the correct error is shown
}
}

The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page. For example://PageObject的方法不做断言,断言由测试代码去做。

 public void testMessagesAreReadOrUnread() {
Inbox inbox = new Inbox(driver);
inbox.assertMessageWithSubjectIsUnread("I like cheese");
inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}

could be re-written as:

public void testMessagesAreReadOrUnread() {
Inbox inbox = new Inbox(driver);
assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}

Of course, as with every guideline there are exceptions, and one that is commonly seen with PageObjects is to check that the WebDriver is on the correct page when we instantiate the PageObject. This is done in the example below.//检查当前页面是不是所需页面。

Finally, a PageObject need not represent an entire page. It may represent a section that appears many times within a site or page, such as site navigation. The essential principle is that there is only one place in your test suite with knowledge of the structure of the HTML of a particular (part of a) page.//PageObject不需要包含整个页面。

Summary

  • The public methods represent the services that the page offers//使用公共方法提供页面的功能。
  • Try not to expose the internals of the page//不要展示页面的内部构造。
  • Generally don't make assertions//不要做断言。
  • Methods return other PageObjects//方法的返回值是一个PageObject。
  • Need not represent an entire page//不需要呈现整个页面。
  • Different results for the same action are modelled as different methods//用不同方法展示一个操作的失败和成功结果。

Example

 public class LoginPage {
private final WebDriver driver; public LoginPage(WebDriver driver) {
this.driver = driver; // Check that we're on the right page.
if (!"Login".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps logging out first
throw new IllegalStateException("This is not the login page");
}
} // The login page contains several HTML elements that will be represented as WebElements.
// The locators for these elements should only be defined once.
By usernameLocator = By.id("username");
By passwordLocator = By.id("passwd");
By loginButtonLocator = By.id("login"); // The login page allows the user to type their username into the username field
public LoginPage typeUsername(String username) {
// This is the only place that "knows" how to enter a username
driver.findElement(usernameLocator).sendKeys(username); // Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
} // The login page allows the user to type their password into the password field
public LoginPage typePassword(String password) {
// This is the only place that "knows" how to enter a password
driver.findElement(passwordLocator).sendKeys(password); // Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
} // The login page allows the user to submit the login form
public HomePage submitLogin() {
// This is the only place that submits the login form and expects the destination to be the home page.
// A seperate method should be created for the instance of clicking login whilst expecting a login failure.
driver.findElement(loginButtonLocator).submit(); // Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won't compile.
return new HomePage(driver);
} // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
public LoginPage submitLoginExpectingFailure() {
// This is the only place that submits the login form and expects the destination to be the login page due to login failure.
driver.findElement(loginButtonLocator).submit(); // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials
// expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
return new LoginPage(driver);
} // Conceptually, the login page offers the user the service of being able to "log into"
// the application using a user name and password.
public HomePage loginAs(String username, String password) {
// The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
typeUsername(username);
typePassword(password);
return submitLogin();
}
}

Support in WebDriver

There is a PageFactory in the support package that provides support for this pattern, and helps to remove some boiler-plate code from your Page Objects at the same time.

Page Objects的更多相关文章

  1. 移动UI自动化-Page Objects Pattern

    移动UI自动化,看起来美好,践行起来却难.做个目光短见的务实主义者.Page Objects Pattern是Selenium官方推崇的方式,最近研究写测试用例最佳实践之Page Objects,同时 ...

  2. [Protractor] Testing With Protractor Page Objects

    Protractor Page Objects are a recommended for testing your AngularJS applications. Page Objects abst ...

  3. [小北De编程手记] [Lesson 02] AutoFramework构建 之 Page Objects - 设计模式

    写在最前面 这个系列的主旨是要跟大家分享一下关于自动化测试框架的构建的一些心得.这几年,做了一些自动化测试框架以及团队的构建的工作.过程中遇到了很多这样的同学,他们在学习了某一门语言和一些自动化测试的 ...

  4. selenium+Page Objects(第三话)

    写好BasePage基类和页面元素定位后,就可以针对每个页面写业务逻辑了 1.编写每个页面page类,拿其中一个页面为例 fourth_page.py(名字我随便取的,实际中希望能取一些有意义的名字) ...

  5. selenium+Page Objects(第一话)

    简单介绍一种selenium用来做web自动化测试的设计模式:Page Objects 一.Page Objects介绍 用官话说它是selenium中的一种页面对象设计模式(不是测试框架!是一种开展 ...

  6. Selenium - WebDriver: Page Objects

    This chapter is a tutorial introduction to page objects design pattern. A page object represents an ...

  7. 通过Java + selenium +testNG + Page Objects 设计模式 实现页面UI的自动化

    Page Objects 设计模式 简单的讲,类似与Java面向对象编程,把每个页面都抽象为一个对象类,将页面元素的定位.业务逻辑操作分离开,然后我们可以通过testNG实现业务流程的控制 与 测试 ...

  8. Selenium关于Page Objects

    介绍页面对象设计模式.一个页面对象表示在你测试的web页面用户交互的界面. 使用页面对象模式的有点: 创建可重用的代码可以在多个测试用例中使用 减少重复的代码量 如果用户界面改变,只需要修改一个地方 ...

  9. selenium+Page Objects(第二话)

    前面介绍了什么是po模式,并且简单分析了一下使用po模式编写脚本的思路,接下来开始正式编写 1.先编写一个页面基类BasePage.py,里面封装每个页面常用的一些方法 # coding: utf-8 ...

随机推荐

  1. Codeforces Gym101572 J.Judging Moose (2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017))

     Problem J Judging Moose 这个题是这里面最简单的一个题... 代码: 1 //J 2 #include <stdio.h> 3 #include <math. ...

  2. Skiing(最短路)

    poj——3037 Skiing Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4921   Accepted: 1315 ...

  3. Xamarin.Forms的滚动视图ScrollView

    Xamarin.Forms的滚动视图ScrollView   在Xamarin.Forms中,滚动视图ScrollView用来实现长内容的滚动显示.虽然ScrollView的Content属性只能设置 ...

  4. 邁向IT專家成功之路的三十則鐵律 鐵律三:IT人長久之道–站對邊

    這一回來談談IT人對於技術的學習.對於一位專業的IT人來說,在自己有興趣的技術領域之中,究竟要如何來正確選擇學習的方向呢?關於這個問題的答案,筆者個人深深體會到這確實會成為一位專業IT人士的長久經營之 ...

  5. Android Studio apk 打包流程(转)http://blog.chinaunix.net/uid-26000296-id-5567890.html

    1.Build -> Generate Signed APK...,打开如下窗口 2.假设这里没有打过apk包,点击Create new,窗口如下 这里只要输入几个必要项 Key store p ...

  6. 【IntelliJ IDEA】idea显示工具栏

    idea显示工具栏 在view->勾选对应按钮即可

  7. C#中如何让ListView控件点击选中整行

    将Listview控件的FullRowSelect属性置为True,当然Listview的View属性应该是Details. 2017年6月25日17:15:55

  8. Cocos2d-x 3.0 打造一个全平台概念文件夹

    Cocos2d-x 3.0 打造一个全平台概念文件夹http:// www.eoeandroid.com/thread-328055-1-1.html

  9. flex操作XML,强力总结帖

    初始化XML对象 XML对象可以代表一个XML元素.属性.注释.处理指令或文本元素.在ActionScript 3.0中我们可以直接将XML数据赋值给变量: var myXML:XML =    &l ...

  10. 10934 - Dropping water balloons(DP)

    这道题的思路非常难想. 问你须要的最少实验次数,这是非常难求解的.并且我们知道的条件仅仅有三个.k.n.实验次数 . 所以我们最好还是改变思路,转而求最高所能确定的楼层数 .  那么用d[i][j]表 ...