• web端自动化——selenium Page Object设计模式


    Page Object设计模式的优点如下:

    ①    减少代码的重复。

    ②    提高测试用例的可读性。

    ③    提高测试用例的可维护性,特别是针对UI频繁变化的项目。

    当为Web页面编写测试时,需要操作该Web页面上的元素。然而,如果在测试代码中直接操作HTML元素,那么你的代码是极其脆弱的,因为UI经常变动。我们可以将一个page对象封装成一个HTML页面,然后通过提供的应用程序特定的API来操作页面元素, 而不是在HTML中四处搜寻。

    Page对象的一个基本经验法则是:凡是人能做的事,Page对象通过软件客户端都能够做到。因此,它也应当提供一个易于编程的接口并隐藏窗口中底层的部件。所以访问一个文本框应该通过一个访问方法(accessor method)来实现字符串的获取与返回,复选框应当使用布尔值,按钮应当被表示为行为导向的方法名。Page对象应当将在GUI控件上所有查询和操作数据的行为封装为方法。一个好的经验法则是,即使改变具体的控件,page对象的接口也不应当发生变化。

    尽管该术语是“页面”对象,但并不意味着需要对每个页面建立一个这样的对象. 例如,页面有重要意义的元素可以独立为一个page对象。经验法则的目的是通过给页面建模,使其对应用程序的使用者变得有意义。

    实例代码如下:

    # -*- coding:utf-8 -*-
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from time import sleep


    class Page(object):

    # 实例化Page类时,最先执行的就是__init__方法,
    # 该方法的入参,其实就是Page类的入参。
    # self指实例本身,相较于类Page而言。
    login_url = 'https://www.126.com'

    def __init__(self, selenium_driver, base_url=login_url):
    self.base_url = base_url
    self.driver = selenium_driver
    self.timeout = 30

    def on_page(self):
    return self.driver.current_url == (self.base_url + self.url)

    # 以单下划线_开头的方法,
    # 在使用import *时,该方法不会被导入,保证该方法为类私有的。
    def _open(self, url):
    url = self.base_url + url
    self.driver.get(url)
    assert self.on_page(), 'Did not land on %s' %url

    # 定义open方法,调用_open()进行打开链接
    def open(self):
    self._open(self.url)

    # loc入参为元组的元素,需要加*。
    # Python存在这种特性,就是将入参放在元组里。
    def find_element(self, *loc):
    return self.driver.find_element(*loc)

    class LoginPage(Page):

    # 126邮箱登录页面模型
    url = '/'
    # 定位器
    # 使用复合类名,直接使用会报错
    username_loc = (By.CLASS_NAME, "dlemail")
    password_loc = (By.CLASS_NAME, "dlpwd")
    submit_loc = (By.ID, "dologin")

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

    def type_username(self, username):
    self.find_element(*self.username_loc).clear()
    self.find_element(*self.username_loc).send_keys(username)

    def type_password(self, password):
    self.find_element(*self.password_loc).send_keys(password)

    def submit(self):
    self.find_element(*self.submit_loc).click()

    def test_user_login(driver, loc, username, password):

    #测试获取的用户名/密码是否可以登录
    login_page = LoginPage(driver)
    login_page.open()
    sleep(5)
    login_page.switch_frame(loc)
    login_page.type_username(username)
    login_page.type_password(password)
    login_page.submit()

    def mainTest():

    try:
    driver = webdriver.Chrome()
    username = 'lili1505115417'
    password = 'lili123456'
    loc = 0
    test_user_login(driver, loc, username, password)
    sleep(5)
    text = driver.find_element_by_id("spnUid").text
    assert (text == 'lili1505115417@126.com'), "用户名称不匹配.登录失敗!"
    finally:
    #关闭浏览器窗口
    driver.quit()
    print('结束')

    if __name__ == '__main__':
    mainTest()


  • 相关阅读:
    linux内核源码之基础准备篇
    GDB 自动化操作的技术-PYTHON
    GDB 调试PYTHON
    GCC onlinedocs
    深入CSS,让网页开发少点“坑”
    多款控件新版发布,新特性抢鲜知
    如何选择前端框架:ANGULAR VS EMBER VS REACT
    推荐10个很棒的AngularJS学习指南
    Top 15 不起眼却有大作用的 .NET功能集
    最全数据结构详述: List VS IEnumerable VS IQueryable VS ICollection VS IDictionary
  • 原文地址:https://www.cnblogs.com/linxiu-0925/p/9948039.html
Copyright © 2020-2023  润新知