Automatización web con Python+selenium: análisis de patrones y casos de PageObject

1. Modo orden de compra

El patrón de objeto de página (PO para abreviar) es el más popular en la práctica de Selenium y es el patrón de diseño más familiar y respetado en las pruebas automatizadas. Al diseñar pruebas automatizadas, abstraiga los elementos de la página y sus métodos de operación de acuerdo con la página, sepárelos en ciertos objetos y luego organícelos.

Uno de los problemas más problemáticos en la automatización web es que la página cambia. Si no se utiliza el patrón de diseño PO, un cambio en la página significa que el posicionamiento anterior del elemento e incluso el método de operación del elemento no se pueden usar y deben revisarse. . Debe averiguar los métodos de posicionamiento de elementos y los métodos de operación de elementos que deben modificarse uno por uno desde el script de prueba y luego modificarlos uno por uno. Estos scripts automatizados no sólo son engorrosos, sino también extremadamente costosos de mantener.

El modo de objeto de página puede resolver muy bien este problema.Ventajas:

  • Reducir la redundancia de código
  • Separación de negocios e implementación.
  • Reducir los costos de mantenimiento

Entonces, ¿qué es el modo de objeto de página? Como sugiere el nombre, es el objeto de página. En las pruebas automatizadas reales, los scripts generalmente se dividen en tres capas:

  • Capa de objeto: utilizada para almacenar el posicionamiento de los elementos de la página.
  • Capa lógica: se utiliza para almacenar algunos módulos de casos de uso funcionales encapsulados.
  • Capa empresarial: utilizada para almacenar la parte operativa de nuestros casos de prueba reales.

Además de las tres capas anteriores, también hay una capa básica. La capa básica es principalmente para algunos métodos comunes de Selenium y se vuelve a encapsular de acuerdo con las necesidades comerciales reales, como hacer clic, ingresar y otras operaciones, y agregar algunas espera, entradas de registros, capturas de pantalla y otras operaciones para mayor comodidad. Verifique el estado de ejecución del script y solucione problemas más adelante.

2. Capa básica

El nombre de la clase de la capa base generalmente se llama BasePage. Las operaciones posteriores de la capa de objetos en los elementos heredan esta clase base. Lo siguiente toma el clic y la entrada como ejemplo:

# basepage.py
import os
import time
import datetime
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from common.logging import log
from common.constant import IMG_DIR


class BasePage:

    def __init__(self, driver: WebDriver):
        self.driver = driver

    def wait_ele_visible(self, loc, img_desc, timeout=20, frequency=0.5):
        """等待元素可见"""
        try:
            WebDriverWait(self.driver, timeout, frequency).until(EC.visibility_of_element_located(loc))
            log.info("等待:{} - 元素{}可见成功。".format(img_desc, loc))
        except:
            log.exception("等待:{} - 元素{}可见失败!".format(img_desc, loc))
            self.save_img(img_desc)
            raise

    def get_element(self, loc, img_desc):
        """查找元素"""
        try:
            ele = self.driver.find_element(*loc)
        except:
            log.exception("查找:{} - 元素{}失败!".format(img_desc, loc))
            self.save_img(img_desc)
            raise
        else:
            log.info("查找:{} - 元素{}成功".format(img_desc, loc))
            return ele

    def click_element(self, loc, img_desc, timeout=20, frequency=0.5):
        """点击元素"""
        self.wait_ele_visible(loc, img_desc, timeout, frequency)
        ele = self.get_element(loc, img_desc)
        try:
            ele.click()
            log.info("点击:{} - 元素{}成功".format(img_desc, loc))
        except:
            log.exception("点击:{} - 元素{}失败!".format(img_desc, loc))
            self.save_img(img_desc)
            raise

    def input_text(self, loc, value, img_desc, timeout=20, frequency=0.5):
        """在元素中输入文本"""
        self.wait_ele_visible(loc, img_desc, timeout, frequency)
        ele = self.get_element(loc, img_desc)
        try:
            ele.send_keys(value)
            log.info("输入:在{} - 元素{}输入文本值({})成功".format(img_desc, loc, value))
        except:
            log.exception("输入:在{} - 元素{}输入文本值({})失败!".format(img_desc, loc, value))
            self.save_img(img_desc)
            raise

    def save_img(self, img_description):
        """保存异常截图"""
        now = time.strftime("%Y-%m-%d %H-%M-%S ", time.localtime())
        img_path = os.path.join(IMG_DIR, now + img_description + '.png')
        try:
            self.driver.save_screenshot(img_path)
        except:
            log.exception("异常截图失败!")
        else:
            log.info("异常截图成功,截图存放在{}".format(img_path))
折叠

Tome click_element() como ejemplo. La operación de espera, la entrada de registro y las capturas de pantalla de excepción se agregan a la encapsulación secundaria aquí. Cuando haga clic en el elemento más tarde, puede llamar directamente a click_element() para hacerlo bien en un solo paso. No es necesario considerar esperas, registros y excepciones. La situación se ha solucionado aquí. Aunque escribir páginas básicas llevará más tiempo en la etapa inicial, siempre que se establezcan las bases, el trabajo de mantenimiento posterior será mucho más costoso. más fácil. Lo anterior es solo un ejemplo y se puede optimizar de acuerdo con sus necesidades reales.

3. Capa de objeto y capa lógica.

La capa de objetos almacena el posicionamiento de los elementos de la página y la capa lógica almacena los métodos de operación de los elementos (funciones de la página). El posicionamiento de los elementos se puede mantener en un módulo separado de acuerdo con las necesidades reales, o se puede almacenar en Excel para una administración centralizada; los elementos se muestran A continuación, los métodos de operación de elementos y posicionamiento se almacenan en un módulo, un módulo por página. Si los elementos de la página posterior cambian, solo necesita modificar la expresión de posicionamiento o el método de operación correspondiente en este módulo.

La demostración toma como ejemplo la página de inicio de Baidu:

# baidu_page.py

from selenium.webdriver.common.by import By
from common.basepage import BasePage


class LoginPage(BasePage):

    login_btn = (By.XPATH, '//div[@id="u1"]//a[@name="tj_login"]')  # 登录按钮
    username_login_btn = (By.ID, 'TANGRAM__PSP_11__footerULoginBtn')    # 用户名登录按钮
    user_input = (By.ID, 'TANGRAM__PSP_11__userName')  # 用户信息输入框
    pwd_input = (By.ID, 'TANGRAM__PSP_11__password')  # 密码输入框
    login_submit = (By.ID, 'TANGRAM__PSP_11__submit')   # 登录提交按钮

    def login(self, user, pwd):
        """
        百度用户名登录
        :param user: 手机/邮箱/用户名
        :param pwd: 密码
        :return:
        """
        self.click_element(self.login_btn, '百度-登录')
        self.click_element(self.username_login_btn, '百度登录-用户名登录')
        self.input_text(self.user_input, user, '用户名登录-手机/邮箱/用户名')
        self.input_text(self.pwd_input, pwd, '用户名登录-密码')
        self.click_element(self.login_submit, '用户名登录-登录')

4. Capa empresarial

Se utiliza para almacenar operaciones de casos de prueba reales. El posicionamiento de elementos y las funciones de página no aparecerán aquí. Todas las operaciones se llaman directamente a la capa lógica.

Caso de prueba = función del objeto de prueba + datos de prueba. Lo siguiente toma el inicio de sesión de Baidu como ejemplo (para demostración, abreviado):

import unittest
import pytest
import ddt
from selenium import webdriver
from PageObjects.baidu_login_page import LoginPage
from testdatas import common_datas as com_d
from testdatas import login_data as lo_d
from common.logging import log


@ddt.ddt
class TestLogin(unittest.TestCase):

    def setUp(self):
        log.info("-------用例前置工作:打开浏览器--------")
        self.driver = webdriver.Chrome()
        self.driver.get(com_d.baidu_url)
        self.driver.maximize_window()

    def tearDown(self):
        self.driver.quit()
        log.info("-------用例后置工作:关闭浏览器--------")

    @pytest.mark.smoke
    def test_login_success(self):
        # 用例:登录页的登录功能
        # 步骤
        LoginPage(self.driver).login(lo_d.success_data['user'], lo_d.success_data['pwd'])
        # 断言.....

​ Resultados de carrera:

Testing started at 11:50 ...
C:\software\python\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.3\helpers\pycharm\_jb_unittest_runner.py" --path D:/learn/test/testcases/test_baidu_login.py
Launching unittests with arguments python -m unittest D:/learn/test/testcases/test_baidu_login.py in D:\learn\test\testcases

Process finished with exit code 0
2022-07-11 11:50:47,238-【test_baidu_login.py-->line:27】-INFO:-------用例前置工作:打开浏览器--------
2022-07-11 11:50:51,327-【basepage.py-->line:38】-INFO:等待:百度-登录 - 元素('xpath', '//div[@id="u1"]//a[@name="tj_login"]')可见成功,耗时0:00:00.056843秒
2022-07-11 11:50:51,339-【basepage.py-->line:77】-INFO:查找:百度-登录 - 元素('xpath', '//div[@id="u1"]//a[@name="tj_login"]')成功
2022-07-11 11:50:51,414-【basepage.py-->line:86】-INFO:点击:百度-登录 - 元素('xpath', '//div[@id="u1"]//a[@name="tj_login"]')成功
2022-07-11 11:50:53,463-【basepage.py-->line:38】-INFO:等待:百度登录-用户名登录 - 元素('id', 'TANGRAM__PSP_11__footerULoginBtn')可见成功,耗时0:00:02.048293秒
2022-07-11 11:50:53,474-【basepage.py-->line:77】-INFO:查找:百度登录-用户名登录 - 元素('id', 'TANGRAM__PSP_11__footerULoginBtn')成功
2022-07-11 11:50:53,535-【basepage.py-->line:86】-INFO:点击:百度登录-用户名登录 - 元素('id', 'TANGRAM__PSP_11__footerULoginBtn')成功
2022-07-11 11:50:53,576-【basepage.py-->line:38】-INFO:等待:用户名登录-手机/邮箱/用户名 - 元素('id', 'TANGRAM__PSP_11__userName')可见成功,耗时0:00:00.040890秒
2022-07-11 11:50:53,584-【basepage.py-->line:77】-INFO:查找:用户名登录-手机/邮箱/用户名 - 元素('id', 'TANGRAM__PSP_11__userName')成功
2022-07-11 11:50:53,714-【basepage.py-->line:98】-INFO:输入:在用户名登录-手机/邮箱/用户名 - 元素('id', 'TANGRAM__PSP_11__userName')输入文本值(15692004245)成功
2022-07-11 11:50:53,759-【basepage.py-->line:38】-INFO:等待:用户名登录-密码 - 元素('id', 'TANGRAM__PSP_11__password')可见成功,耗时0:00:00.043882秒
2022-07-11 11:50:53,771-【basepage.py-->line:77】-INFO:查找:用户名登录-密码 - 元素('id', 'TANGRAM__PSP_11__password')成功
2022-07-11 11:50:53,925-【basepage.py-->line:98】-INFO:输入:在用户名登录-密码 - 元素('id', 'TANGRAM__PSP_11__password')输入文本值(phang0209)成功
2022-07-11 11:50:53,958-【basepage.py-->line:38】-INFO:等待:用户名登录-登录 - 元素('id', 'TANGRAM__PSP_11__submit')可见成功,耗时0:00:00.031914秒
2022-07-11 11:50:53,969-【basepage.py-->line:77】-INFO:查找:用户名登录-登录 - 元素('id', 'TANGRAM__PSP_11__submit')成功
2022-07-11 11:50:54,051-【basepage.py-->line:86】-INFO:点击:用户名登录-登录 - 元素('id', 'TANGRAM__PSP_11__submit')成功
2022-07-11 11:50:56,426-【test_baidu_login.py-->line:35】-INFO:-------用例后置工作:关闭浏览器--------


Ran 1 test in 9.191s

OK

A juzgar por el registro de salida, cada paso de la operación es claramente visible y los problemas se pueden localizar rápidamente y optimizarlos de acuerdo con las necesidades reales.

  • modo orden de compra
  • capa base
  • Capa de objeto y capa lógica
  • Capa empresarial

Finalmente: Los siguientes son los materiales de aprendizaje de apoyo, que deberían ser el almacén de preparación más completo y completo para los amigos que hacen [pruebas de software]. Este almacén también me ha acompañado en el viaje más difícil. ¡Espero que también pueda ayudarlo a usted!

Subprograma de entrevista de prueba de software

¡Un banco de preguntas de prueba de software que ha sido utilizado por millones de personas! ! ! ¡Quién es quién lo sabe! ! ! El miniprograma de prueba de entrevistas más completo de Internet. Puede usar su teléfono móvil para responder preguntas, tomar el metro, el autobús y enrollarlo.

Cubre las siguientes secciones de preguntas de la entrevista:

1. Teoría básica de pruebas de software, 2. web, aplicaciones, pruebas de función de interfaz, 3. red, 4. base de datos, 5. linux

6. Web, aplicaciones, automatización de interfaces, 7. Pruebas de rendimiento, 8. Conceptos básicos de programación, 9. Preguntas de la entrevista de recursos humanos, 10. Preguntas de prueba abiertas, 11. Pruebas de seguridad, 12. Conceptos básicos de informática

  Cómo obtener el conjunto completo de información: haga clic en la pequeña tarjeta a continuación para obtenerla usted mismo

Supongo que te gusta

Origin blog.csdn.net/weixin_57794111/article/details/132900677
Recomendado
Clasificación