Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
---
title: "Page object models"
title: "PO设计模式"
weight: 1
---

{{% notice info %}}
<i class="fas fa-language"></i> 页面需要从英语翻译为简体中文。
您熟悉英语与简体中文吗?帮助我们翻译它,通过 pull requests 给我们!
{{% /notice %}}

Page Object is a Design Pattern which has become popular in test automation for
enhancing test maintenance and reducing code duplication. A page object is an
object-oriented class that serves as an interface to a page of your AUT. The
tests then use the methods of this page object class whenever they need to
interact with the UI of that page. The benefit is that if the UI changes for
the page, the tests themselves don’t need to change, only the code within the
page object needs to change. Subsequently all changes to support that new UI
are located in one place.

The Page Object Design Pattern provides the following advantages:

* There is a clean separation between test code and page specific code such as
locators (or their use if you’re using a UI Map) and layout.
* There is a single repository for the services or operations offered by the page
rather than having these services scattered throughout the tests.

In both cases this allows any modifications required due to UI changes to all
be made in one place. Useful information on this technique can be found on
numerous blogs as this ‘test design pattern’ is becoming widely used. We
encourage the reader who wishes to know more to search the internet for blogs
on this subject. Many have written on this design pattern and can provide
useful tips beyond the scope of this user guide. To get you started, though,
we’ll illustrate page objects with a simple example.

First, consider an example, typical of test automation, that does not use a
page object:

PO(page object)设计模式是在自动化中已经流行起来的一种易于维护和减少代码的设计模式. 在自动化测试中, PO对象作为一个与页面交互的接口.
测试中需要与页面的UI进行交互时, 便调用PO的方法. 这样做的好处是, 如果页面的UI发生了更改,那么测试用例本身不需要更改, 只需更改PO中的代码即可.

PO设计模式具有以下优点:

* 测试代码与页面的定位代码(如定位器或者其他的映射)相分离.
* 该页面提供的方法或元素在一个独立的类中, 而不是将这些方法或元素分散在整个测试中.

这允许在一个地方修改由于UI变化所带来的所有修改. 随着这种"测试设计模式"的广泛使用, 可以在众多博客中找到有关此技术的有用信息.
我们鼓励希望了解更多信息的读者在互联网上搜索有关此主题的博客. 许多人已经写过这种设计模式, 并且可以提供超出本用户指南范围的有用提示.
不过, 为了让您入门, 我们将通过一个简单的示例来说明页面对象.

首先, 思考一个不使用PO模式的自动化测试的典型案例:

```java
/***
Expand All @@ -42,29 +25,24 @@ page object:
public class Login {

public void testLogin() {
// fill login data on sign-in page
// 在登录页面上填写登录数据
driver.findElement(By.name("user_name")).sendKeys("testUser");
driver.findElement(By.name("password")).sendKeys("my supersecret password");
driver.findElement(By.name("sign-in")).click();

// verify h1 tag is "Hello userName" after login
// 登录后验证h1标签是否为Hello userName
driver.findElement(By.tagName("h1")).isDisplayed();
assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
}
}
```

There are two problems with this approach.
这种方法有两个问题.

* There is no separation between the test method and the AUT’s locators (IDs in
this example); both are intertwined in a single method. If the AUT’s UI changes
its identifiers, layout, or how a login is input and processed, the test itself
must change.
* The ID-locators would be spread in multiple tests, in all tests that had to
use this login page.
* 测试方法与定位器 (在此实例中为By.name)耦合过于严重. 如果测试的用户界面更改了其定位器或登录名的输入和处理方式, 则测试本身必须进行更改.
* 在对登录页面的所有测试中, 同一个定位器会散布在其中.

Applying the page object techniques, this example could be rewritten like this
in the following example of a page object for a Sign-in page.
可以在以下登录页面的示例中应用PO设计模式重写此示例.

```java
import org.openqa.selenium.By;
Expand Down Expand Up @@ -103,7 +81,7 @@ public class SignInPage {
}
```

and page object for a Home page could look like this.
Home page的PO如下所示.

```java
import org.openqa.selenium.By;
Expand Down Expand Up @@ -139,13 +117,12 @@ public class HomePage {
// Page encapsulation to manage profile functionality
return new HomePage(driver);
}
/* More methods offering the services represented by Home Page
of Logged User. These methods in turn might return more Page Objects
for example click on Compose mail button could return ComposeMail class object */
/* 提供登录用户主页所代表的服务的更多方法. 这些方法可能会返回更多页面对象.
例如, 单击"撰写邮件"按钮可以返回ComposeMail类对象 */
}
```

So now, the login test would use these two page objects as follows.
那么, 接下来的登录测试用例将使用这两个页面对象.

```java
/***
Expand All @@ -163,31 +140,18 @@ public class TestLogin {
}
```

There is a lot of flexibility in how the page objects may be designed, but
there are a few basic rules for getting the desired maintainability of your
test code.

Page objects themselves should never make verifications or assertions. This is
part of your test and should always be within the test’s code, never in an page
object. The page object will contain the representation of the page, and the
services the page provides via methods but no code related to what is being
tested should be within the page object.

There is one, single, verification which can, and should, be within the page
object and that is to verify that the page, and possibly critical elements on
the page, were loaded correctly. This verification should be done while
instantiating the page object. In the examples above, both the SignInPage and
HomePage constructors check that the expected page is available and ready for
requests from the test.

A page object does not necessarily need to represent an entire page. The Page
Object design pattern could be used to represent components on a page. If a
page in the AUT has multiple components, it may improve maintainability if
there is a separate page object for each component.

There are other design patterns that also may be used in testing. Some use a
Page Factory for instantiating their page objects. Discussing all of these is
beyond the scope of this user guide. Here, we merely want to introduce the
concepts to make the reader aware of some of the things that can be done. As
was mentioned earlier, many have blogged on this topic and we encourage the
reader to search for blogs on these topics.
PO的设计方式具有很大的灵活性, 但是有一些基本规则可以使测试代码具有理想的可维护性.

PO本身绝不应进行判断或断言. 判断和断言是测试的一部分, 应始终在测试的代码内, 而不是在PO中.
PO用来包含页面的表示形式, 以及页面通过方法提供的服务, 但是与PO无关的测试代码不应包含在其中.

实例化PO时, 应进行一次验证, 即验证页面以及页面上可能的关键元素是否已正确加载.
在上面的示例中, SignInPage和HomePage的构造函数均检查预期的页面是否可用并准备接受测试请求.

PO不一定需要代表整个页面. PO设计模式可用于表示页面上的组件.
如果自动化测试中的页面包含多个组件, 则每个组件都有单独的页面对象, 则可以提高可维护性.

还有其他设计模式也可以在测试中使用. 一些使用页面工厂实例化其页面对象. 讨论所有这些都不在本用户指南的范围之内.
在这里, 我们只想介绍一些概念, 以使读者了解可以完成的一些事情.
如前所述, 许多人都在此主题上写博客, 我们鼓励读者搜索有关这些主题的博客.