Python y selenium_project articles_project combate real, optimización de código, refactorización del proyecto

En el combate real, solo quiero decir una cosa: escribir casos de uso que cubran funciones básicas en combinación con el proyecto en el que se encuentra actualmente. Cuando encuentres un problema, resuélvelo, persevera, habrás terminado.
Antecedentes: el código es el proceso de reserva de entradas en Ctrip.com.
(1) Directorio de archivos, cada código de directorio
(2) Optimización y reconstrucción de código, introducción al marco de nivel de código,
(3) Manejo de excepciones, manejo de registros, espera inteligente

(1) Consulte el código:
Inserte la descripción de la imagen aquí
función de capa de código básica.py

# coding=utf-8
from datetime import datetime,date,timedelta
from selenium import webdriver
import logging,os,xlrd,xlwt
import urllib3

# 以下为driver设置和打开携程火车票网站
# driver = webdriver.Chrome()
'''
函数return_driver()的功能是返回driver对象
'''
def return_driver():
    return driver
'''
函数open_base_site(url)的功能是打开携程火车票首页面
'''
def open_base_site(url):
    driver.get(url)
'''
函数date_n(n)将返回n天后的日期
'''
def date_n(n):
    return str((date.today() + timedelta(days = +int(n))).strftime("%Y-%m-%d"))
'''
函数id将返回按照id属性来定位元素的语句
'''
def id(element):
    return driver.find_element_by_id(element)
'''
函数css将返回css selector方式来定位元素的语句
'''
def css(element):
    return driver.find_element_by_css_selector(element)
'''
函数xpath将返回xpath方式来定位元素的语句
'''
def xpath(element):
    return driver.find_element_by_xpath(element)
'''
函数js通过selenium来执行javascript语句
'''
def js(element):
    driver.execute_script(f"document.getElementById(f'{element}').removeAttribute('readonly')")
'''
函数log()定义了日志的输出格式
'''
def log(str):
    # 日志基础配置
    logging.basicConfig(
        level=logging.INFO, # 定义了日志的输出级别
        datefmt='%a,%d,%b,%Y,%H:%M:%S', # 定义了日志输出的时间格式
        filename='D:\\ui_date\\log-selenium.log', # 定义了日志输出路径文件
        filemode='a', #日志以追加的形式进入log-selenium.log
        format='%(asctime)s%(filename)s%(levelname)s%(message)s' # 定义了日志的输出形式
    )
    # 定义streamhandler格式的日志
    console = logging.StreamHandler()
    # 设置日志格式
    console.setFormatter(logging.INFO)
    console.setFormatter(logging.Formatter('%(name)-12s:%(levelname)-8s %(message)s'))
    # 给日志添加定义后的handler
    logging.getLogger('').addHandler(console)
    logging.info(str)
'''
函数read_excel是输出第几列的内容,如果不给cloumn的值,默认是以列表的形式输出所有内容
filename:文件路径一直到文件
index:索引值第几页
cloumn:第几列
'''
def read_excel(filename,index,cloumn):
    # 打开excel文件,filename是绝对路径或者相对路径下的文件
    xls = xlrd.open_workbook(filename)
    # 打开第几个sheet页
    sheet = xls.sheet_by_index(index)
    # print(sheet.nrows) 行
    # print(sheet.ncols) 列
    # 内容以字典的形式输出,不给cloum值,默认是输出所有表哥的所有内容
    dic={
    
    }
    for j in range(sheet.ncols):
        date=[]
        for i in range(sheet.nrows):
            date.append(sheet.row_values(i)[j])
        dic[j]=date
    return dic

if __name__ == "__main__":
    logging.log(logging.DEBUG,"我是dbug级别的")
    logging.log(logging.INFO,"我是info级别的")
    logging.log(logging.WARNING,"我是warning级别的")
    logging.log(logging.ERROR,"我是error级别的")
    logging.log(logging.CRITICAL,"我是critical级别的")

Capa de código comercial search_tickets.py

'''
此页面的功能是测试火车票查询的页面元素
'''
from selenium.webdriver.common.action_chains import ActionChains
from functions import date_n,id,css,xpath,js,return_driver,open_base_site
from selenium import webdriver
import time

'''
函数名:search_tickets
参数:
    from_station:出发站
    to_station:到达站
    n:是一个数字,如1表示选择明天的车票,2表示选择后天的车票
'''
def search_tickets(from_station,to_station,n):
    driver = return_driver()
    open_base_site('https://trains.ctrip.com/')
    driver.maximize_window()
    driver.implicitly_wait(10)

    # from_station = '上海'
    from_station = from_station
    # to_station = '杭州'
    to_station = to_station

    # 以下为tommorrow变量
    tomorrow = date_n(n)
    # 以下为定位出发城市和到达城市的页面元素,设置其值为以上定义值
    css('[placeholder="出发城市"]').send_keys(from_station)
    id("arriveCityName").send_keys(to_station)

    # 移除出发时间的“readonly”属性
    js("date0bj")
    time.sleep(2)

    # 清除出发时间的默认值
    id('dateObj').clear()
    time.sleep(2)

    # 以下定位为搜索车次日期
    id('dateObj').send_keys(tomorrow)

    # 以下步骤是为了解决日期控件弹出框在输入日期后无法消失的问题,以防影响测试的进行,原理是鼠标点击空白处
    ActionChains(driver).move_by_offset(0,0).click().perform()

    # 单击“车次搜索”按钮
    id('searchbtn').click()

# 实例化类,run才有结果
if __name__ == '__main__':
    search_tickets("上海","杭州",1)

Capa de código de prueba test_booking_tickets.py

import time
from functions import date_n,id,css,xpath,js,return_driver,open_base_site
from search_tickets import search_tickets

# 搜索网站火车票列表
search_tickets("上海","杭州",1)
driver = return_driver()
time.sleep(2)
# 点击预订按钮
xpath("/html/body/div[7]/div/div[5]/div[3]/div/div[1]/div[6]/div[1]/a").click()
# 输入乘客姓名
css('[placeholder="姓名,请与所持证件上的一致"]').send_keys("小张")

(2) Optimización y refactorización del
código La optimización del código tiene 2 puntos:
1. Reducir la cantidad de código, aumentar la tasa de reutilización, mejorar la solidez (en el caso de big data), la legibilidad y la capacidad de expansión.
2. Mejorar la legibilidad del código y el código pesado. La estructura se puede implementar con una función definida. Tal como:

# coding=utf-8
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys

# 定义函数部分,减少代码量的且提高复用率,如果定义函数的部分必须放在测试代码前面。
def id(element):
    return driver.find_element_by_id(element)
def css(element):
    return driver.find_element_by_css_selector(element)
def xpath(element):
    return driver.find_element_by_xpath(element)
def js(element):
    return driver.execute_script("document.getElementById(" + "'" + element + "'" + ").removeAttribute('readonly')")

driver = webdriver.Chrome()
driver.get("https://www.hao123.com/")
driver.maximize_window()
# 百度网站的id值
id("kw").click()
css([adsads="sdfs"]).click()

Refactorización de código
A medida que aumenta el código, las funciones y los códigos de prueba se colocan en un archivo, que es difícil de expandir y mantener, por lo tanto, agregue variables a la función de manera adecuada y evite la codificación rígida. El objetivo final es hacer que el código de prueba sea más conciso y claro.
El código del proyecto se divide en una estructura de tres niveles: la estructura del código y las ideas deben estar bien planificadas en la etapa inicial de automatización, y el código se hará cada vez más grande en la etapa posterior.
1. Capa de código de prueba
2. Capa de código comercial
3. Capa de código básico

Capa de código básica: encapsula la configuración relacionada de selenium y webdriviver, como el contenido de function.py

# coding=utf-8
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys

# 定义函数部分,减少代码量的且提高复用率
# coding=utf-8
from selenium import webdriver
import time

# 以下为driver设置和打开测试网站
driver = webdriver.Chrome()

# def return_driver():
#     return driver
# 打开网页
# def open_base_site(url):
#     driver.get(url)

# 定义函数部分,减少代码量的且提高复用率
def id(element):
    return driver.find_element_by_id(element)
def css(element):
    return driver.find_element_by_css_selector(element)
def xpath(element):
    return driver.find_element_by_xpath(element)
def js(element):
    return driver.execute_script("document.getElementById(" + "'" + element + "'" + ").removeAttribute('readonly')")

Capa de código comercial:

"""
函数名:lang
参数:
    a是url
    b是用户名
    c是密码
"""
def land(a,b,c):
    driver = webdriver.Chrome()
    driver.get(f"{a}")
    driver.find_element_by_id("kw").send_keys(f"{b}")
    driver.find_element_by_id('mn').send_keys(f"{c}")
    driver.find_element_by_id('submit').click()
    time.sleep(1)
    driver.maximize_window()

Capa de código de prueba:

实现了测试用例。

La llamada refactorización y optimización significa que a medida que avanza el proyecto, necesitamos cambiar la capa de código básica y la capa de código comercial para que nuestra capa de código de prueba se pueda llevar a cabo mejor.

1. Manejo de excepciones 1. Manejo de
excepciones de selenio, consulte el manejo de excepciones de la automatización de la interfaz, eso es muy bueno, las excepciones comunes son las siguientes:

# coding=utf-8
import selenium
import logging

# 操作数据库的方法
class OperationDbInterface(object):
    # 初始化数据库连接
    def __int__(self, a):
        try:
            if 0 == 0:
                pass
            else:
                print("i")
            # 打开游标
            print("ok")
        except error as e:
            print('创建数据库失败|Mysql Error %d: %s' % (e.args[0], e.args[1]))
            # 配置日志格式
            logging.basicConfig(filename=config.src_path + 'E:/log/syserror.log', level=logging.DEBUG,
                                format='%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s %(message)s')
            # 获取日志
            logger = logging.getLogger(__name__)
            # 输出日志
            logger.exception(e)
            
# selenium常见的9种异常。
# (1)NoSuchElementException:选择器返回元素失败时,抛出异常
# (2)ElementNotVisibleException:定位的元素在DOM中存在,在页面不显示,不能交互时
# (3)ElementNotSelectableException:选择了不可选的元素
# (4)NoSuchFrameException:要切换的frmae不存在
# (5)NoSuchWindowException:要切换的新窗口不存在
# (6)TimeoutException:当代码执行时间超出时
# (7)NoSuchAttributeException:元素的属性找不到
# (8)UnexpectedTagNameException:当支持类没有获得预期的web元素时
# (9)NoAlertPresentException:一个意外的警告

Dos, una breve introducción al módulo de registro

# coding=utf-8
import logging
'''
函数log()定义了日志的基础配置
'''
def log(str):
    # 日志基础配置
    logging.basicConfig(
        level=logging.INFO, # 定义了日志的输出级别
        datefmt='%a,%d,%b,%Y,%H:%M:%S', # 定义了日志输出的时间格式
        filename='D:\\ui_date\\log-selenium.log', # 定义了日志输出路径文件
        filemode='a', #日志以追加的形式进入log-selenium.log
        format='%(asctime)s%(filename)s%(levelname)s%(message)s' # 定义了日志的输出形式
    )
    # 定义streamhandler格式的日志
    console = logging.StreamHandler()
    # 设置日志格式
    console.setFormatter(logging.INFO)
    console.setFormatter(logging.Formatter('%(name)-12s:%(levelname)-8s %(message)s'))
    # 给日志添加定义后的handler
    logging.getLogger('').addHandler(console)
    logging.info(str)

if __name__ == "__main__":
    logging.log(logging.DEBUG,"我是dbug级别的")
    logging.log(logging.INFO,"我是info级别的")
    logging.log(logging.WARNING,"我是warning级别的")
    logging.log(logging.ERROR,"我是error级别的")
    logging.log(logging.CRITICAL,"我是critical级别的")

3. Espera inteligente
Debido a que es demasiado problemático agregar tiempo de espera antes de cada operación de elemento de posicionamiento, agregue el tiempo de espera inteligente global: driver.implicitly_wait (10)
significa: entre todas las operaciones de posicionamiento, el navegador espera más de 10 segundos, más de 10 segundos reportarán un error

# coding=utf-8
from selenium import webdriver
import time
from selenium.common import exceptions as ex

driver = webdriver.Chrome()
driver.get("https://www.hao123.com/")
driver.maximize_window()
driver.implicitly_wait(10)

Supongo que te gusta

Origin blog.csdn.net/weixin_45451320/article/details/112585768
Recomendado
Clasificación