PO模式简介与示例

文章目录

简介

PO模式(Page Object Model)是自动化测试项目开发实践的最佳设计模式之一。

它的主要用途是把一个具体的页面转换成编程语言当中的一个对象,页面特性转化成对象属性,页面操作转换成对象方法。

在自动化测试当中,主要用来实现对页面操作和测试,逻辑的一个分离,PO思想最开始来源于马丁富勒(marktin Flewer)在2004年发表的一篇文章。最初是叫作Window driver,后来selenium沿用这种思想,后来就改成了POM。

PO模式的核心思想是通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化,只需要调整页面元素封装的代码,提高测试用例的可维护性、可读性。

优点

  • 代码可读性高,减少冗余代码;
  • 增加用例的可维护性,业务代码和测试代码被分开,降低耦合性维护成本低;
  • 增强复用性。

基本原则

方法意义

  • 用公共方法来代表UI所提供的功能
    如:首页的搜索功能,名站功能
  • 方法应该返回其他的page object或者返回用于断言的数据
    如,首页点击搜索框进入搜索页面
  • 相同的行为不同的结果,可以建模不同的方法
    如:登录行为可以拆分成登录成功(进入首页),或者登录失败(仍然停留在登录页面)
  • 不会在PO内创建断言

字段意义

  • 不要暴露页面内的元素给外部
    如:页面内的按钮的id不能被其他的case调用(变化的元素都控制在PO内部)
  • 不需要建模整个页面元素
    如:每个页面的元素不需要全部列出来,用到什么写什么

用例分层

基于 POM 的用例组织结构,良好的分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复用性。

一般而言,可以分以下几层:

  • page:完成对页面的封装
  • testcase:调用各类 page 完成业务流程并进行断言
  • driver:完成对 Web、Android、iOS、接口的驱动
  • data:配置文件和数据驱动
  • utils:其他便捷的功能封装,可选

demo

测试demo:雪球app
操作步骤:打开首页 --> 点击搜索框 --> 输入股票代码 --> 断言股票价格是否大于1快

原始测试脚本

from appium import webdriver

class TestDemo:
    def setup(self):
        caps = {
            'platformName': 'Android',
            'appPackage': 'com.xueqiu.android',
            'appActivity': '.view.WelcomeActivityAlias',
            'noReset': True,
            'skipServerInstallation': True
        }

        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', caps)
        self.driver.implicitly_wait(10)

    def test_search(self):
        """
        原脚本
        """
        self.driver.find_element_by_id("com.xueqiu.android:id/home_search").click()  # 点击首页搜索框
        self.driver.find_element_by_id("search_input_text").send_keys('二三四五')  # 输入股票代码
        self.driver.find_element_by_id("name").click()  # 点输入联想列表的股票名称

        price = self.driver.find_element_by_id("current_price")  # 获取股票价格

        assert float(price.text) > 1.0  # 断言是否大于1元

    def teardown(self):
        self.driver.quit()

PO模式

编写用例的顺序

  • 根据界面封装page类与方法()
  • 编写用例,不断重构明确 page 里方法的入参和返回值
  • 开始实现 page 内的方法
    • 把这个页面需要的一些核心操作封装成方法
    • 在有页面发生跳转的情况下,发生跳转的方法需要返回跳转页面的类对象

testcase

from page.app import App


class TestDemo:
    def setup(self):
        self.search_page = App.start().to_search()

    def test_search_po(self):
        self.search_page.search('二三四五')
        assert self.search_page.get_current_price() > 1.0

    def teardown(self):
        App.quit()

page

  • app.py
from appium import webdriver
from selenium.webdriver.remote.webdriver import WebDriver

from page.main_page import MainPage


class App:
    driver: WebDriver = None

    @classmethod
    def start(cls):
        """
        启动app:后进入首页
        :return: 首页
        """
        caps = {
            'platformName': 'Android',
            'appPackage': 'com.xueqiu.android',
            'appActivity': '.view.WelcomeActivityAlias',
            'noReset': True,
            'skipServerInstallation': True
        }

        cls.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', caps)
        cls.driver.implicitly_wait(10)

        return MainPage(cls.driver)

    @classmethod
    def quit(cls):
        cls.driver.quit()
  • main_page.py
from selenium.webdriver.remote.webdriver import WebDriver

from page.search_page import SearchPage


class MainPage(object):
    def __init__(self, driver: WebDriver):
        self.driver = driver

    def to_search(self):
        self.driver.find_element_by_id("com.xueqiu.android:id/home_search").click()  # 点击首页搜索框
        return SearchPage(self.driver)
  • search_page.py
from selenium.webdriver.remote.webdriver import WebDriver


class SearchPage(object):
    def __init__(self, driver: WebDriver):
        self.driver = driver

    def search(self, keyword):
        self.driver.find_element_by_id("search_input_text").send_keys(keyword)  # 输入股票代码
        self.driver.find_element_by_id("name").click()  # 点输入联想列表的股票名称
        return self

    def get_current_price(self):
        return float(self.driver.find_element_by_id("current_price").text)
上一篇:Kubemark压测常用命令


下一篇:再不会就被淘汰了--自动化测试的PO模式详解