UI自动化测试_6_Page Object 设计模式

为了解决代码的可重复性和可维护性,对于持续自动化测试很重要的.

开发的信条是: 不做重复的自己, 不写重复的代码

为了解决 上边的问题, Page Object 走上了舞台,跳了一支绚丽的舞蹈.

什么是 Page Object ?

简单的说是 创建对象 对应页面的一个应用.

我们可以把每个页面构建一个类,并且为页面的属性和方法 构建模型.

这就相当于 测试脚本 和 被测的页面 分离一层,屏蔽了定位器,操作方法和业务逻辑.

页面有任何页面元素的改动,并不会影响测试脚本改动.

优点如下:

  1. 降低 开发人员修改页面 对测试脚本的影响
  2. 可以在多测试用例 用同一套代码,达到了复用

举例说明如下:

做以下封装 1. browser 2. 封装 page共同的方法 3. page 的定位元素 和操作方法 4. 测试代码

browser

  1. 在Browser 类 里 init
    判断传入的 浏览器的类型,并返回webdriver.chrome ,
    代码如下:
TYPES = {'firefox': webdriver.Firefox, 'chrome': webdriver.Chrome, 'ie': webdriver.Ie, 'phantomjs': webdriver.PhantomJS}
EXECUTABLE_PATH = {'firefox': 'wires', 'chrome': CHROMEDRIVER_PATH, 'ie': IEDRIVER_PATH, 'phantomjs': PHANTOMJSDRIVER_PATH}


class UnSupportBrowserTypeError(Exception):
    pass


class Browser(object):
    def __init__(self, browser_type='firefox'):
        self._type = browser_type.lower()
        if self._type in TYPES:
            self.browser = TYPES[self._type]
        else:
            raise UnSupportBrowserTypeError('仅支持%s!' % ', '.join(TYPES.keys()))
        self.driver = None
  1. 封装get 方法
    get 方法包含 三个部分 1). 返回一个webdriver 对象,2). 判断是否全屏 3).加入全局等待方式 默认为0
  def get(self, url, maximize_window=True, implicitly_wait=30):
        self.driver = self.browser(executable_path=EXECUTABLE_PATH[self._type])
        self.driver.get(url)
        if maximize_window:
            self.driver.maximize_window()
        self.driver.implicitly_wait(implicitly_wait)
        return self
  1. 封装截屏方法
    判断路径是否存在,如果不存在就创建,
    格式化时间, 调用 save_screenshot(file_path) 并返回 截屏对象
      def save_screen_shot(self, name='screen_shot'):
        day = time.strftime('%Y%m%d', time.localtime(time.time()))
        screenshot_path = REPORT_PATH + '\screenshot_%s' % day
        if not os.path.exists(screenshot_path):
            os.makedirs(screenshot_path)

        tm = time.strftime('%H%M%S', time.localtime(time.time()))
        screenshot = self.driver.save_screenshot(screenshot_path + '\\%s_%s.png' % (name, tm))
        return screenshot
  1. 浏览器关闭 方法,也放在这里面
   def close(self):
        self.driver.close()

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

封装 page共同的方法

重写方法如下, find_element , send_keys , switch_to_frame,switch_to_alert,Select()
代码如下;

from selenium.webdriver.support.select import Select

from test_01.common.browser import Browser


class Page(Browser):
    # 更多的封装请自己动手...
    def __init__(self, page=None, browser_type='chrome'):
        if page:
            self.driver = page.driver

        else:
            super(Page, self).__init__(browser_type=browser_type)

    def get_driver(self):

        return self.driver

    def select_dropdownlist(self,*args):
        return  Select(self.driver.find_element(*args))

    def find_element(self, *loc):
        #        return self.driver.find_element(*loc)
        try:
            # 确保元素是可见的。
            # 注意:以下入参为元组的元素,需要加*。Python存在这种特性,就是将入参放在元组里。
            #            WebDriverWait(self.driver,10).until(lambda driver: driver.find_element(*loc).is_displayed())
            # 注意:以下入参本身是元组,不需要加*
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))
            return self.driver.find_element(*loc)
        except:
            print
            u"%s 页面中未能找到 %s 元素" % (self, loc)

        # 重写switch_frame方法

    def switch_frame(self, loc):
        return self.driver.switch_to_frame(loc)

        # 定义script方法,用于执行js脚本,范围执行结果

    def script(self, src):
        self.driver.execute_script(src)

        # 重写定义send_keys方法

    def send_keys(self, loc, vaule, clear_first=True, click_first=True):
        try:
            loc = getattr(self, "_%s" % loc)  # getattr相当于实现self.loc
            if click_first:
                self.find_element(*loc).click()
            if clear_first:
                self.find_element(*loc).clear()
                self.find_element(*loc).send_keys(vaule)
        except AttributeError:
            print
            u"%s 页面中未能找到 %s 元素" % (self, loc)


3. page 的定位元素 和操作方法

from selenium.webdriver.common.by import By
from test_01.common.page import Page


class BaiDuMainPage(Page):
    loc_search_input = (By.ID, 'kw')
    loc_search_button = (By.ID, 'su')

    def search(self, kw):
        """搜索功能"""
        self.find_element(*self.loc_search_input).send_keys(kw)
        self.find_element(*self.loc_search_button).click()

测试代码

只是 跟page 的方法进行交互, 不同的场景调用不同组合的方法。 跟定位元素完全脱离, 示例代码如下;

这个是我以前的项目的代码

import time
import unittest
from utils.config import Config, DATA_PATH, REPORT_PATH
from utils.log import logger
from utils.file_reader import ExcelReader


from test_01.page.TA.quote_page   import Quote_page
from test_01.page.TA.plan_page import Plan_page
from test_01.page.TA.Insured_page import Insured_page
from test_01.page.TA.confirm_pay_page import Comfirm_pay
from test_01.page.TA.pament_page import Payment
from test_01.common.page import Page


class Smoke_TA_Product(unittest.TestCase):
    URL = Config().get('URL_TA')

    excel = DATA_PATH + '/baidu.xlsx'


    page = Quote_page(browser_type='chrome').get(URL, maximize_window=True,implicitly_wait=40)

    def sub_tearDown(self):
        self.page.quit()

    def test_smoke01_quote_page(self):
        logger.info("test_quote")
        self.page.quote_page()
        #执行quote page
    def test_smoke02_plan_page(self):
        self.page = Plan_page(self.page)

        self.page.plan_page()
        #执行plan page
    def test_smoke03_insured_page(self):
        self.page = Insured_page(self.page)

        self.page.insured_page()

        #执行insured page
    def test_smoke04_confirm_pay(self):
        self.page=Comfirm_pay(self.page)
        self.page.confirm_pay()

      #执行  confirm and pay page
    def test_smoke04_pay(self):
        self.page=Payment(self.page)
        self.page.pay()




你可能感兴趣的:(UI,自动化面试题)