【Selenium学习】Page Object 设计模式

章节目录

前言

一、认识

二、优点

三、实现 Paget Object

1.Paget Object 简单实例

2.改进 Paget Object 封装

总结


前言

Page Object 是 UI 自动化测试项目开发实践的最佳设计模式之一,它的主要特点体现在对界面交互细节的封装上,使测试用例更专注于业务的操作,从而提高测试用例的可维护性。

一、认识

        Page Object模式下,应用程序中的每个网页都被表示为一个单独的类或对象。Page Object包含与该页面交互所需的所有方法和属性,例如查找元素、点击按钮、填写表单和检索数据等。

        通过使用Page Objects,测试人员可以创建更有组织和可重用的代码,并减少重复代码的数量。Page Objects还使得更新测试更加容易,如果应用程序的UI发生变化,只需要在相应的Page Object类中进行更改即可。

二、优点

1. 提高可读性

使用Page Objects,测试代码变得更加可读和易于理解。测试人员可以轻松地在Page Objects中编写可读的代码,而无需直接操作浏览器的底层API。这使得测试代码更易于维护和调试,同时也降低了测试代码的复杂度。

2. 提高可维护性

使用Page Objects,测试人员可以将UI元素和测试代码分开,从而提高代码的可维护性。如果UI元素发生了变化,测试人员只需要在相应的Page Object类中进行更改,而无需在测试代码中查找和更新所有与该元素相关的代码。这样可以大大减少代码的维护成本和时间。

3. 提高可扩展性

使用Page Objects,测试人员可以轻松地添加新的测试用例和新的页面。由于每个页面都有一个对应的Page Object类,因此只需创建一个新的Page Object类即可为新页面添加测试用例。这使得测试自动化框架更加灵活和可扩展。

4. 降低重复代码的数量

使用Page Objects,测试人员可以将通用的代码块抽象到Page Objects中,并在需要时重复使用。这可以减少测试代码的重复量,并提高代码的可重用性。此外,这还可以减少测试代码中的错误,并提高测试代码的质量。

三、实现 Paget Object

        下面我们将通过例子介绍这种设计模式的使用。

1.Paget Object 简单实例

        以百度搜索为列,假设我们有如下测试代码:
...

def test_baidu_search_case1(self):
    self.driver.get(self.base_url)
    self.driver.find_element(By.ID, "kw").send_keys("selenium")
    self.driver.find_element(By.ID, "su").click()
def test_baidu_search_case2(self):
    self.driver.get(self.base_url)
    self.driver.find_element(By.ID, "kw").send_keys("unittest")
    self.driver.find_element(By.ID, "su").click()
def test_baidu_search_case3(self):
    self.driver.get(self.base_url)
    self.driver.find_element(By.ID, "kw").send_keys("page object")
    self.driver.find_element(By.ID, "su").click()

...
        这段代码最大的问题就是在三条测试用例中重复使用了元素的定位和操作。这会带来
一个很大的问题,当元素的定位发生变化后,例如,id=kw 失效了,应及时调整定位方法,
这时就需要在三条测试用例当中分别进行修改。
        假设,我们的自动化项目有几百条测试用 例,而 UI 很可能是频繁变化的,那么就会提高自化测试用例的维护成本。
        Page Object 的设计思想上是把元素定位与元素操作进行分层,这样带的来最直接的好
处就是当元素发生变化时,只需维护 page 层的元素定位,而不需要关心在哪些测试用例当
中使用了这些元素。在编写测试用例时,也不需要关心元素是如何定位的。
        创建 baidu_page.py 文件,内容如下:
# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/4/3
"""

from selenium.webdriver.common.by import By


class BaiduPage():
    def __init__(self, driver):
        self.driver = driver

    def search_input(self, search_key):
        self.driver.find_element(By.ID, "kw").send_keys(search_key)

    def search_button(self):
        self.driver.find_element_by_id("su").click()
        首先创建 BaiduPage 类,在__init__()初始化方法中接收参数 driver 并赋值给 self.driver。
然后,分别封装 search_input()方法和 search_button()方法,定位并操作元素。这里的封装只
针对一个页面中可能会操作到的元素,原则上是一个元素封装成一个方法。当元素的定位
方法发生改变时,只需维护这里的方法即可,而不需要关心这个方法被哪些测试用例使用了。
# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/4/3
"""

import unittest
from selenium import webdriver
from baidu_page import BaiduPage


class TestBaidu(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()
        self.baidu_url = 'https://www.baidu.com'

    def test_baidu_search_case1(self):
        self.driver.get(self.baidu_url)
        bd = BaiduPage(self.driver)
        bd.search_input("selenium")
        bd.search_button()

    def test_baidu_search_case2(self):
        self.driver.get(self.baidu_url)
        bd = BaiduPage(self.driver)
        bd.search_input("unittest")
        bd.search_button()

    def test_baidu_search_case3(self):
        self.driver.get(self.baidu_url)
        bd = BaiduPage(self.driver)
        bd.search_input("page object")
        bd.search_button()

    def tearDown(self):
        self.driver.close()


if __name__ == '__main__':
    unittest.main
        首先在测试中导入 BaiduPage 类,然后在每个测试用例中为 BaiduPage 类传入驱动,
这样就可以轻松地使用它封装的方法来设计具体的测试用例了。这样做的目的就是在测试
用例中消除元素定位。如果你要操作百度输入框,那么只需调用 search_input()方法并传入
搜索关键字即可,并不需要关心百度输入框是如何定位的。

2.改进 Paget Object 封装

        以上代码仍存在一些问题,比如以前一条测试用例只需写 4 到 5 行 代码即可,现在却不得不先在 Page 层针对每个待操作的元素进行封装,然后再到具体的测试用例中引用。为了使 Page 层的封装更加方便,我们做一些改进。
        创建 base.py 文件,内容如下。
# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/4/3
"""

from selenium.webdriver.common.by import By


class BasePage:
    """
    基础 Page 层,封装一些常用方法
    """

    def __init__(self, driver):

        self.driver = driver

    # 打开页面
    def open(self, url=None):
        if url is None:
            self.driver.get(self.url)
        else:
            self.driver.get(url)

    # id 定位
    def by_id(self, id_):
        return self.driver.find_element(By.ID, id_)

    # name 定位
    def by_name(self, name):
        return self.driver.find_element(By.NAME, name)

    # class 定位
    def by_class(self, class_name):
        return self.driver.find_element(By.CLASS_NAME, class_name)

    # XPath 定位
    def by_xpath(self, xpath):
        return self.driver.find_element(By.XPATH, xpath)

    # CSS 定位
    def by_css(self, css):
        return self.driver.find_element(By.CSS_SELECTOR, css)

    # 获取 title
    def get_title(self):
        return self.driver.title

    # 获取页面 text,仅使用 XPath 定位
    def get_text(self, xpath):
        return self.by_xpath(xpath).text

    # 执行 JavaScript 脚本
    def js(self, script):
        self.driver.execute_script(script)
        创建 BasePage 类作为所有 Page 类的基类,在 BasePage 类中封装一些方法,这些方法
是我们在做自动化时经常用到的。
        下面修改 baidu_page.py 文件:
# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/4/3
"""

from base import BasePage


class BaiduPage(BasePage):
    """百度 Page 层,百度页面封装操作到的元素"""
    url = "https://www.baidu.com"

    def search_input(self, search_key):
        self.by_id("kw").send_keys(search_key)

    def search_button(self):
        self.by_id("su").click()
        在 search_input()和 search_button()方法中使用了父类的 self.by_id()方法来定位元素,比
原生的 Selenium 方法简短了不少。
        在测试用例中,使用 BaiduPage 类及它所继承的父类中的方法:
# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/4/3
"""

import unittest
from time import sleep
from selenium import webdriver
from baidu_page import BaiduPage


class TestBaidu(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Firefox()

    def test_baidu_search_case(self):
        page = BaiduPage(self.driver)
        page.open()
        page.search_input("selenium")
        page.search_button()
        sleep(2)
        self.assertEqual(page.get_title(), "selenium_百度搜索")

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)
        因为前面封装了元素的定位,所以在编写测试用例时会方便不少,当需要用到哪个 Page
类时,只需将它传入浏览器驱动,就可以使用该类中提供的方法了。

总结

Page Object模式是一个非常有用的测试自动化设计模式,可以提高测试代码的可读性、可维护性和可扩展性,同时还可以降低测试代码的复杂度和重复量,提高测试代码的质量和效率。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: 好的,我会尽力帮助您。 首先,我们需要了解PageObject设计模式的基本思想。PageObject设计模式是一种用于描述Web应用程序用户界面的方法。它通过分离用户界面的元素和操作来使测试代码更加可维护和可读。 在Selenium中使用PageObject设计模式,我们需要创建一个类,该类描述了特定页面的元素和操作。这个类通常被称为“PageObject”。 例如,假设我们正在测试一个在线商店的登录页面。我们可以创建一个名为“LoginPage”的类,该类描述了登录页面上的所有元素,如用户名输入框、密码输入框和登录按钮。我们还可以在该类中定义方法来描述如何使用这些元素来执行操作,如输入用户名和密码并点击登录按钮。 下面是一个使用PageObject设计模式的简单示例,该示例描述了如何使用Selenium来测试登录页面: ```python from selenium import webdriver class LoginPage: def __init__(self, driver): self.driver = driver self.url = "http://www.example.com/login" self.username_input = self.driver.find_element_by_id("username") self.password_input = self.driver.find_element_by_id("password") self.login_button = self.driver.find_element_by ### 回答2: Page Object模式是一个常用的设计模式,用于改进Selenium项目的可维护性和可扩展性。基于Page Object模式的Selenium项目分为三个主要部分:测试用例、页面对象和测试执行。 首先,我们需要创建测试用例。测试用例是描述需要执行的操作和验证点的脚本。在编写测试用例时,我们应该尽可能地让测试用例保持简洁、可读性高,并且降低测试用例之间的耦合度。 接下来,我们需要创建页面对象。页面对象是Selenium页面的抽象表示,包含页面的各种元素和对应的操作方法。每个页面对象应该对应应用程序的一个页面或一个功能模块。 然后,我们将测试用例和页面对象结合起来进行测试执行。在测试执行过程中,我们通过实例化页面对象,调用其方法来操作页面元素和执行各种操作。这样的测试执行方式使得代码复用更加容易,同时使得代码更加可读性和可维护性。 在项目中,我们可以使用Selenium WebDriver来驱动浏览器,通过定位元素和操作元素来实现各种操作。使用Java语言编写测试用例和页面对象可以更好地与Selenium WebDriver集成。 通过使用基于Page Object设计模式Selenium项目,我们可以降低测试用例的复杂度,提高测试脚本的可读性和可维护性。同时,通过封装页面对象,我们可以减少测试用例的重复代码,提高代码复用性,并且便于测试脚本的扩展和维护。 总结起来,基于Page Object设计模式Selenium项目能够提高代码的可读性、可维护性和可扩展性,使得测试执行更加灵活和高效。 ### 回答3: 基于Page Object设计模式Selenium项目可以用于自动化测试Web应用程序。下面我给你一个简单的示例: 1. 首先,创建一个新的Java项目,然后添加Selenium WebDriver的依赖项。 2. 创建一个名为"LoginPage"的类来表示登录页面,并继承自"BasePage"类。LoginPage类应该包含登录页面的元素定位和操作方法,如输入用户名、输入密码、点击登录按钮等。 3. 创建一个名为"HomePage"的类来表示登录成功后的首页,并同样继承自"BasePage"类。HomePage类应该包含首页的元素定位和操作方法,如检查欢迎信息、点击注销按钮等。 4. 创建一个名为"BasePage"的基类,其中封装Selenium WebDriver的初始化和公共操作方法。在BasePage中,你可以初始化WebDriver并定义一些常用的操作方法,如点击、输入等。 5. 创建一个名为"LoginTest"的类来执行登录测试。在LoginTest中,你可以创建LoginPage对象并调用其中的方法,如输入用户名和密码,然后点击登录按钮。接着,你可以创建HomePage对象并验证欢迎信息是否正确。如果成功登录,运行测试应该会通过。 总结:基于Page Object设计模式Selenium项目可以帮助我们实现更高效和可维护的自动化测试。通过将页面对象和操作方法封装到独立的类中,我们可以更好地组织和管理测试代码,并提高测试脚本的重用性。当应用程序发生变化时,我们只需要更新相应的页面对象,而不用修改每个测试用例。这样的设计模式能够提高测试代码的可读性、可维护性和健壮性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胖虎*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值