• Selenium:PO模型设计


    1、什么是PO设计模式 (Page Object Model)
    一种在测试自动化中变得流行的设计模式,使得自动化测试脚本的减少代码重复、更易读、减少维护成本。

    一般PO设计模式有三层
    第一层:

    • 对Selenium 进行二次封装,定义一个所有页面都继承的 BasePage ,
    • 封装 Selenium 基本方法 例如:元素定位,元素等待,导航页面 ,
    • 不需要全部封装,用到多少方法就封装多少方法。

    第二层:

    • 页面元素进行分离,每个元素只定位一次,隔离定位,如果页面改变,只需要改变相应的元素定位;
    • 业务逻辑分离 或 操作元素动作分离

    第三层:

    • 使用单元测试框架对业务逻辑进行测试

    2、为什么要使用PO设计模式

    • 页面频繁变化,(页面html结构等变化)导致页面UI元素频繁变动,元素定位改变
    • 传统线性自动化(面向过程开发),用例中需要反复的定位同一个元素
    • 每当页面发生变化的时候,需要在用例中寻找变动的部分,工作量大,容易产生遗漏,不容易维护

    3、使用PO设计模式要点

    • 不要在page页面对象外做元素定位
    • 不在page页面对象里面写断言,除非是页面是否成功加载断言
    • 需要多少个元素就定位多少个,不需要对整个页面的元素进行定位
    • 当你的用例设计页面跳转时,例如登陆操作,登陆完成后跳转首页,当页面发生“跳转”
      ,封装的业务逻辑需要返回(return)对应的页面对象的实例
    • BasePage封装Selenium 基础方法,不需要全部封装,用到多少方法就封装多少方法

    4、 PO设计模式实例

      实例登录Ecshop并选中商品编辑

    • base封装底层元素
    • page对页面元素定位
    • report生成测试报告
    • testcase编写测试用例
    • main.py执行
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.select import Select
    
    
    class Base:
    
        def __init__(self, driver):
            self.driver = driver
            self.driver.maximize_window()
    
        def go_page(self, url):
            self.driver.get(url)
    
        def find_element(self, *loc):
            return self.driver.find_element(*loc)
    
        def find_elements(self,*loc):
            return self.driver.find_elements(*loc)
    
        def send_key(self, text, *loc):
            self.find_element(*loc).send_keys(text)
    
        def ele_clear(self, *loc):
            self.find_element(*loc).clear()
    
        def ele_click(self, *loc):
            self.find_element(*loc).click()
    
        def eles_click(self,num,*loc):
            self.driver.find_elements(*loc)[num].click()
    
        def page_title(self):
            return self.driver.title
    
        def web_quit(self):
            self.driver.quit()
    
        def wait_title_content(self, title):
            WebDriverWait(self.driver, 5).until(EC.title_contains(title))
    
        def enter_frame(self,*loc):
            self.driver.switch_to.frame(*loc)
    
        def quit_frame(self):
            self.driver.switch_to.default_content()
    
        def select_index(self,index,*loc):
            Select(self.driver.find_element(*loc)).select_by_index(index)
    
        def select_value(self,value,*loc):
            Select(self.driver.find_element(*loc)).select_by_value(value)
    
        def select_text(self,text,*loc):
            Select(self.driver.find_element(*loc)).select_by_visible_text(text)
    base_element
     1 from selenium.webdriver.common.by import By
     2 
     3 from Ecshop.base.base_element import Base
     4 from selenium import webdriver
     5 
     6 class LoginPage(Base):
     7     page_url = 'http://41.hdy1314.com/admin/privilege.php?act=login'
     8     login_username = (By.NAME, 'username')
     9     login_password = (By.NAME, 'password')
    10     login_submit = (By.CLASS_NAME, 'btn-a')
    11     menu_frameid = (By.ID,'menu-frame')
    12     menu_id02 = (By.XPATH, '//*[@id="menu-ul"]/li[2]')
    13     main_frameid = (By.ID,'main-frame')
    14     cat_id = (By.NAME,'cat_id')
    15     submit_btn01 = (By.XPATH, '/html/body/div[9]/form/button')
    16     #redact = (By.XPATH,'//*[@id="listDiv"]/table[1]/tbody/tr[3]/td[13]/a[2]')
    17     redact = (By.LINK_TEXT, '编辑')
    18 
    19 
    20 
    21     def __init__(self):
    22         driver = webdriver.Chrome()
    23         Base.__init__(self, driver)
    24         self.go_page(self.page_url)
    25 
    26     def send_username(self,text):
    27         self.send_key(text, *self.login_username)
    28 
    29     def send_password(self,text):
    30         self.send_key(text, *self.login_password)
    31 
    32     def submit(self):
    33         self.ele_click(*self.login_submit)
    34 
    35     def menu_frame(self):
    36         return self.find_element(*self.menu_frameid)
    37 
    38     def menu(self):
    39         self.ele_click(*self.menu_id02)
    40 
    41     def main_frame(self):
    42         return self.find_element(*self.main_frameid)
    43 
    44     def select_cat(self,num):
    45         self.select_index(num,*self.cat_id)
    46 
    47     def submit_btn(self):
    48         self.ele_click(*self.submit_btn01)
    49 
    50     def click_redact(self,num):
    51         if len(self.find_elements(*self.redact)) > num:
    52             self.eles_click(num,*self.redact)
    53         else:
    54 
    55             print("元素组的长度小于%s" %(num + 1))
    login_page
     1 import time
     2 from Ecshop.page.login_page import LoginPage
     3 import allure
     4 
     5 @allure.feature('ECSHOP')
     6 class TestSearch:
     7 
     8     def setup_class(self):
     9 
    10         self.ecshop_login = LoginPage()
    11 
    12     @allure.story('登录Ecshop')
    13     @allure.description('登录账号进入管理后台')
    14     @allure.title("ECSHOP管理中心")
    15     def test_case3(self):
    16         self.ecshop_login.send_username('admin')
    17         self.ecshop_login.send_password('admin123')
    18         self.ecshop_login.submit()
    19         #self.ecshop_login.wait_title_content('admin')
    20         assert self.ecshop_login.page_title() == 'ECSHOP 管理中心'
    21         tt = self.ecshop_login.menu_frame()
    22         self.ecshop_login.enter_frame(tt)
    23         self.ecshop_login.menu()
    24         self.ecshop_login.quit_frame()
    25         xf =self.ecshop_login.main_frame()
    26         self.ecshop_login.enter_frame(xf)
    27         self.ecshop_login.select_cat(5)
    28         self.ecshop_login.submit_btn()
    29         time.sleep(3)
    30         self.ecshop_login.click_redact(1)
    31 
    32     def teardown_class(self):
    33         time.sleep(5)
    34         self.ecshop_login.web_quit()
    test_search
    import os
    import pytest
    
    if __name__ == '__main__':
        pytest.main(['-vs', "./testcase/test_search.py", "--alluredir", "./report/allure-result"])
        os.system(r"allure generate --clean ./report/allure-result -o ./report/allure-report")
    main
  • 相关阅读:
    AJAX初步学习
    MyBatis 中@param 的用法
    MyBatis 分页
    MyBatis 中一对一和一对多的映射关系
    MyBatis的增删改查。
    MyBatis配置文件
    java 中 “==” 和 equals 的区别
    点云格式-pcd
    VS2015+VisualSVN+TortoiseSVN安装及使用
    GIS中的引擎:地图引擎
  • 原文地址:https://www.cnblogs.com/mtfan01/p/15705614.html
Copyright © 2020-2023  润新知