zoukankan      html  css  js  c++  java
  • Python_Selenium 之以login_page为例实现对basepage封装好的方法调用和对common中公共方法的调用

    目的:简化代码,提供框架该有的东西
    每一个函数 -提供了一个功能 - 公共的功能
    有了basepage,在PageObjects当中直接调用元素操作。

    以下以login_page 为例,实现从配置文件中读取基础信息,日志模块,公共方法login.py的封装,从Excel中读取元素信息,login_page.py 调用basepage中公共操作方法操作。

    一、basepage类代码如下:

    #coding=gbk
    import os
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By #导入by方法
    from selenium.webdriver.support.wait import WebDriverWait #隐式等待
    from common.log_utils import logger #导入日志模块

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

    # ----------浏览器操作封装-------
    #打开网页
    def open_url(self,url):
    self.driver.get(url)
    logger.info('打开URL地址%s;'%url)

    def set_browser_max(self):
    self.driver.maximize_window()
    logger.info("设置浏览器的最大化")

    # -------- 元素识别的封装--------
    def find_element(self,element_info):
    locator_type_name=element_info['locator_type']
    locator_value_info=element_info['locator_value']
    locator_timeout=element_info['timeout']
    if locator_type_name =='id':
    locator_type=By.ID
    elif locator_type_name=='class':
    locator_type=By.CLASS_NAME
    elif locator_type_name=='xpath':
    locator_type=By.XPATH
    #识别元素
    element=WebDriverWait(self.driver,locator_timeout)
    .until(lambda x:x.find_element(locator_type,locator_value_info))
       #在basepage中添加日志打印,这样就能实现每一个调用该方法的元素打印该日志,且日志记录清晰明了,不需要再在每一个UIpage 中增加日志。
            logger.info('[%s]元素识别成功'%element_info['element_name'])  
    return element

    #元素鼠标操作封装:点击
    def click(self,element_info):
    element=self.find_element(element_info)
    logger.info('[%s]元素进行点击操作'%element_info['element_name'])
    element.click()

    # #键盘事件操作封装:输入内容
    def input(self,element_info,content):
    element=self.find_element(element_info)
    element.send_keys(content)
    logger.info('[%s]元素输入内容:%s'%(element_info['element_name'],content))

    --日志打印模块 log_utils.py(目前简单封装)
    import os
    import logging

    current_path = os.path.dirname(__file__)
    log_path = os.path.join( current_path ,'../logs/test.log' )

    class LogUtils:
    def __init__(self,logfile_path = log_path ):
    self.logfile_path = logfile_path
    self.logger = logging.getLogger('Logger')
    self.logger.setLevel(level=logging.INFO)
    file_log = logging.FileHandler(self.logfile_path)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_log.setFormatter(formatter)
    self.logger.addHandler(file_log)

    def info(self,message):
    self.logger.info( message )

    def error(self,message):
    self.logger.error(message)

    logger = LogUtils()

    if __name__=='__main__':
    log_utils = LogUtils()
    log_utils.info( '测试打印输出' )

    二、调用如下(以登录页面login_page.py 例):

    (1)login_page.py 主代码如下:
    #coding=gbk
    import os
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from common.log_utils import logger
    from common.base_page import BasePage
    from common.config_utils import config
    from common import login
    from common.set_driver import set_driver
    from common.element_data_utils import ElementdataUtils
    from common.element_yamldate_utils import ElementdataYamlUtils

    class LoginPage(BasePage):
    def __init__(self,driver):
    super().__init__(driver)
    ####-----------------第一种方式,直接写字典形式---------------------####
    # self.username_inputbox = {'element_name':'用户名输入框',
    # 'locator_type':'xpath',
    # 'locator_value':'//input[@name="account"]',
    # 'timeout': 5 }
    # self.password_inputbox = {'element_name': '密码输入框',
    # 'locator_type': 'xpath',
    # 'locator_value': '//input[@name="password"]',
    # 'timeout': 4}
    # self.login_button = {'element_name': '登录按钮',
    # 'locator_type': 'xpath',
    # 'locator_value': '//button[@id="submit"]',
    # 'timeout': 2}
    ####-----------------第二种方式,使用excecl读取---------------------####
    elements=ElementdataUtils('login_page').get_element_info()
    #####公共####
    self.username_inputbox =elements['username_inputbox']
    self.password_inputbox=elements['password_inputbox']
    self.login_button=elements['login_button']
    self.change_language=elements['change_language']

    def input_username(self,username): #方法 == 》控件的操作
    self.input( self.username_inputbox , username )

    def input_password(self,password):
    self.input( self.password_inputbox , password )

    def click_login(self):
    self.click( self.login_button )

    if __name__=="__main__":
    from common.base_page import BasePage
    driver=set_driver()
    login_page = LoginPage(driver)
    login.test_login(config.get_url,config.get_user_name,config.get_password,driver) ##因为封装了登录方法,直接调用即可

    (2)公共方法:登录login.py封装
    from selenium import  webdriver
    from element_infos.login_page import LoginPage
    from common.config_utils import config
    from common.set_driver import set_driver

    def test_login(url, username, password, driver):
    driver.get(url)
    login = LoginPage(driver)
    login.input_username(username)
    login.input_password(password)
    login.click_login()

    (3)公共方法:config_utils.py 配置信息封装
    import os
    import configparser

    current_path = os.path.dirname(__file__)
    cfgpath = os.path.join(current_path, "../conf/local_config.ini")
    print(cfgpath)

    class ConfigUtils:
    def __init__(self,config_path=cfgpath):
    self.__conf=configparser.ConfigParser() ##做成私有实例属性,仅在类的内部使用,外部不可访问,也提高使用的简洁度
    self.__conf.read(config_path, encoding="utf-8")

    def read_ini(self,sec,option):
    value=self.__conf.get(sec,option)
    return value

    @property #添加这个可将该类的这个方法变成一个类属性,直接调用类的属性就可以
    def get_url(self):
    value=self.read_ini('default','url')
    return value


    @property #添加这个可将该类的这个方法变成一个类属性,直接调用类的属性就可以
    def get_user_name(self):
    value=self.read_ini('user','user_name')
    return value

    @property
    def get_password(self):
    value = self.read_ini('user', 'password')
    return value

    @property
    def get_error_user_name(self):
    value=self.read_ini('user','error_user_name')
    return value

    @property
    def get_error_password(self):
    value = self.read_ini('user', 'error_password')
    return value

    config=ConfigUtils() #直接定义一个方法,在外部直接调用该方法就可以,不需要再每次都创建一个对象

    if __name__=='__main__':
    current_path = os.path.dirname(__file__)
    cfgpath = os.path.join(current_path, "../conf/local_config.ini")
    config_u=ConfigUtils()
    print(config_u.get_url)
    print(config_u.get_user_name)
    print(config_u.get_password)

    local_config.ini配置如下:
    [default]
    url=http://127.0.0.1/zentao/user-login-L3plbnRhby9teS5odG1s.html

    [user]
    user_name = admin
    password = XXXXXXX
    (4)公共方法:element_data_utils.py  配置信息封装
    import  os
    import xlrd

    current_path=os.path.dirname(__file__)
    excel_path=os.path.join(current_path,'../element_info_datas/element_infos.xlsx')

    class ElementdataUtils:
    def __init__(self,page_name,element_path=excel_path):
    self.element_path=element_path
    self.workbook = xlrd.open_workbook(excel_path)
    self.sheet = self.workbook.sheet_by_name(page_name)
    self.row_count=self.sheet.nrows

    def get_element_info(self):
    element_infos = {}
    for i in range(1, self.sheet.nrows):
    element_info = {}
    element_info['element_name'] = self.sheet.cell_value(i, 1)
    element_info['locator_type'] = self.sheet.cell_value(i, 3) ##所属页面不要取值
    element_info['locator_value'] = self.sheet.cell_value(i, 4)
    element_info['timeout'] = self.sheet.cell_value(i, 5)
    element_infos[self.sheet.cell_value(i, 0)] = element_info
    return element_infos

    if __name__ == '__main__':
    print(ElementdataUtils('login_page').get_element_info())
    print(ElementdataUtils('main_page').get_element_info()

    元素Excel信息配置:
    (4)公共方法:set_driver.py  浏览器简单封装
    from selenium import webdriver

    def set_driver():
    driver = webdriver.Chrome()
    driver.maximize_window()
    return driver

    if __name__ == '__main__':
    set_driver()

    结论:

    一、在login_page.py 中,引入basepage,定义元素字典信息(字典信息在Excel中存放),定义当前login页面的元素操作(loginpage对元素操作此处调用basepage中公共的元素操作方法--->basepage内部再去调用basepage中的元素识别和元素操作),各个模块方法组合调用,PO模式实现登录。

    二、将常用的方法做成公共方法,方便调用,比如对元素信息的读取,登录方法login.py,配置文件的读取等。

    三、测试数据和代码分离,方便维护,比如excecl存放元素信息,采用xlrd模块读取数据为字典形式。



  • 相关阅读:
    活动安排问题
    CodeForces
    HDU
    HDU
    HihoCoder
    二分签到题--二分入门
    并查集,最小生成树
    spark和 mapreduce的比较
    SparkSQL--数据源Parquet的加载和保存
    SparkSQL -DataFrame与RDD的互转
  • 原文地址:https://www.cnblogs.com/123anqier-blog/p/12825723.html
Copyright © 2011-2022 走看看