Cuando se trata de automatizar pruebas de front-end, elegir el lenguaje de programación ideal se vuelve extremadamente crucial. Python es uno de esos lenguajes que encabeza la lista, gracias a su facilidad de uso y al amplio apoyo de la comunidad.
Además, la automatización de pruebas en Python te permite aprovechar las capacidades que ofrecen bibliotecas y marcos populares como Selenium, pytest y Robot, entre otros. Usar Selenium con Python ayuda a aprovechar al máximo las potentes capacidades de automatización de navegadores de Selenium y la simplicidad y extensibilidad de Python. En general, la automatización de pruebas en Python es ampliamente utilizada por QAs en todo el mundo, especialmente con Selenium WebDriver.
En este blog, profundizaremos en las sutilezas de Python desde una perspectiva de front-end. Los aprendizajes de este blog serán útiles para aprovechar las capacidades de Python para automatizar escenarios de front-end simples y complejos.
¿Qué es la automatización de pruebas en Python?
Como su nombre indica, la automatización de pruebas en Python es el proceso de utilizar scripts de Python para automatizar pruebas. Es uno de los lenguajes de programación más buscados para la automatización de tareas manuales y repetitivas.
Un ejemplo simple de pruebas de automatización en Python implica aprovechar el marco pytest con Selenium para automatizar pruebas de front-end en una plataforma de comercio electrónico. Puedes verificar la funcionalidad de registro de un sitio web de comercio electrónico y usar la misma sesión para navegar por el sitio y agregar los artículos necesarios al carrito de compras. Al final de esta prueba, habrás verificado las funcionalidades de registro, inicio de sesión y carrito del sitio web de comercio electrónico.
Por último, también puedes aprovechar Python para automatizar la administración del sistema, automatizar correos electrónicos y tareas de procesamiento de datos. Dado que Python es un requisito previo para pruebas automatizadas, consulta el video a continuación, que profundiza en la instalación de Python.
¿Por qué Python para pruebas automatizadas?
Ahora que sabemos por qué los evaluadores prefieren Selenium con Python, veamos algunas de las razones esenciales para elegir Python para pruebas de automatización:
1. Amplia gama de bibliotecas y marcos
PyUnit (o unittest) es el marco de prueba predeterminado para realizar pruebas unitarias con Python. Aunque PyUnit está disponible de forma predeterminada, Python admite otros marcos populares como pytest, Behave, Robot, Lettuce y Nose2.
Todos ellos se pueden utilizar exhaustivamente con los marcos Selenium y Playwright para automatizar pruebas en navegadores web.
2. Ejecución de pruebas paralelas súper fácil
Las pruebas paralelas en Selenium y Python se pueden utilizar ampliamente para realizar pruebas de automatización en navegadores web en diferentes combinaciones de navegadores y plataformas. Aunque todos los lenguajes compatibles con Selenium admiten la ejecución de pruebas paralelas, es muy fácil de usar con Python.
3. Lenguaje de Programación Multi-Paradigma
Python es un lenguaje de programación multi-paradigma. Por lo tanto, tiene un soporte completo para la programación orientada a objetos y la programación estructurada. La mayoría de las características en Python admiten la programación funcional y la programación orientada a aspectos. Python, junto con Selenium, también se puede utilizar para probar sitios web y aplicaciones web de forma funcional.
4. Tipado Dinámico
El lenguaje Python utiliza tipado dinámico y enlace tardío (o resolución de nombres dinámica) que enlaza los métodos y nombres de variables durante la ejecución. Esta característica es muy útil para la automatización de pruebas en Python.
Python también ofrece opciones como Pyre (un verificador de tipos de alto rendimiento para Python 3) y Mypy, que son verificadores de tipos estáticos populares. Con estos verificadores, Python te permite combinar el poder del tipado dinámico y estático.
5. Web Scraping
El web scraping con Python es el proceso de extraer información/datos significativos y útiles de sitios web. Se utiliza principalmente para investigaciones académicas, análisis de competidores, agregación de contenido y más.
Python ofrece una serie de bibliotecas y frameworks, como BeautifulSoup (bs4), Selenium, Puppeteer y Pyppeteer, que facilitan la tarea de extraer contenido de sitios web.
6. Reporting Potente y sin Problemas
Los informes en la automatización de pruebas proporcionan una mayor visibilidad sobre los matices de la ejecución de pruebas (es decir, porcentaje de pruebas aprobadas/fallidas, entorno de prueba, capturas de pantalla, etc.). Informes poderosos que brindan la información correcta de manera concisa y comprensible pueden ser enviados a los interesados necesarios (en el equipo) para que estén al tanto del progreso en el frente de pruebas.
¿Cómo realizar pruebas de automatización en Python?
Ahora que hemos analizado la importancia de las pruebas de automatización en Python, pongámonos manos a la obra ejecutando algunas pruebas. Nuestra discusión se centrará principalmente en las pruebas automatizadas de front-end con Python.
Antes de comenzar con las pruebas, configuremos el entorno virtual (venv
), que ayuda a gestionar mejor el entorno y las dependencias. venv
juega un papel fundamental al proporcionar aislamiento de los paquetes instalados en el entorno base.
Ejecute los comandos virtualenv venv
y source venv
/bin
/activate
en la terminal para crear el entorno virtual. Todas las dependencias (o paquetes de Python), como pytest
, selenium
, etc., requeridas para la ejecución del proyecto están disponibles en el archivo requirements.txt.
pytest-selenium
pytest-xdist
selenium>=4.6.0
urllib3==1.26.12
requests
py
Dependencias
Las dependencias se pueden instalar ejecutando pip install -r requirements.txt
en la terminal. Selenium v4.6.0 (o superior) se instala como parte del procedimiento de instalación.
Para la demostración, ejecutaríamos pruebas simples de Selenium en Python con los frameworks pytest y PyUnit (o unittest). Si tienes un buen conocimiento de cualquiera de estos frameworks, se recomienda que utilices fixtures en Python y el Modelo de Objetos de Página en Selenium Python para mejorar el mantenimiento de las pruebas. El paquete Selenium en sí no proporciona una herramienta o framework de pruebas. Por lo tanto, usaríamos Selenium con pytest y PyUnit para automatizar las interacciones con los elementos en la página web.
Escenario de Prueba
- Navega a LambdaTest Selenium Playground.
- Localiza el enlace de Formulario de Entrada Enviar en la página.
- Ingresa la información requerida en la página.
- Envía los detalles y verifica si la información no se ha enviado correctamente.
Implementación (Framework pytest)
A continuación se muestra el script de prueba para el escenario de prueba anterior:
import os
import pytest
from os import environ
import time
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
exec_platform = os.getenv('EXEC_PLATFORM')
time_sleep = 2
########################## Locators #########################
xSubmitForm = "//a[.='Input Form Submit']"
xInpName = "//input[@id='name']"
cInpName = "#name"
xInpEmail = "//form[@id='seleniumform']//input[@name='email']"
xInpPassword = "//input[@name='password']"
cssCompany = "#company"
cWebName = "#websitename"
xInpCountry = "//select[@name='country']"
xInpCity = "//input[@id='inputCity']"
cssAddress1 = "[placeholder='Address 1']"
cssAddress2 = "[placeholder='Address 2']"
cssInpState = "#inputState"
cssInpZip = "#inputZip"
cssInpButton = ".bg-lambda-900"
nameSearchBox = "search"
class TestFormInput:
def setup_method(self):
if exec_platform == 'cloud':
username = environ.get('LT_USERNAME', None)
access_key = environ.get('LT_ACCESS_KEY', None)
ch_options = webdriver.ChromeOptions()
lt_options = {}
lt_options["build"] = "Build: Getting Started with Selenium PyTest"
lt_options["project"] = "Project: Getting Started with Selenium PyTest"
lt_options["name"] = "Test: Getting Started with Selenium PyTest"
lt_options["browserName"] = "Chrome"
lt_options["browserVersion"] = "latest"
lt_options["platformName"] = "macOS Sonoma"
lt_options["geoLocation"] = "US"
lt_options["console"] = "error"
lt_options["w3c"] = True
lt_options["headless"] = False
ch_options.set_capability('LT:Options', lt_options)
gridURL = "https://{}:{}@hub.lambdatest.com/wd/hub".format(username, access_key)
self.driver = webdriver.Remote(
command_executor = gridURL,
options = ch_options
)
elif exec_platform == 'local':
ch_options = ChromeOptions()
self.driver = webdriver.Chrome(options=ch_options)
def test_enter_form_details(self):
resultant_str = "Thanks for contacting us, we will get back to you shortly."
driver = self.driver
driver.get("https://www.lambdatest.com/selenium-playground/")
# Commented once the tests are executed in non-headless mode
driver.maximize_window()
wait = WebDriverWait(driver, 5)
try:
element = driver.find_element(By.XPATH, xSubmitForm)
element.click()
elem_name = driver.find_element(By.XPATH, xInpName)
elem_name.send_keys("Testing")
time.sleep(time_sleep)
elem_email = driver.find_element(By.XPATH, xInpEmail)
elem_email.send_keys("[email protected]")
time.sleep(time_sleep)
elem_pass = driver.find_element(By.XPATH, xInpPassword)
elem_pass.send_keys("password")
time.sleep(time_sleep)
elem_comp = driver.find_element(By.CSS_SELECTOR, cssCompany)
elem_comp.send_keys("LambdaTest")
elem = driver.find_element(By.CSS_SELECTOR, cWebName)
elem.send_keys("https://wwww.lambdatest.com")
country_dropdown = Select(driver.find_element(By.XPATH, xInpCountry))
country_dropdown.select_by_visible_text("United States")
time.sleep(time_sleep)
elem = driver.find_element(By.XPATH, xInpCity)
elem.send_keys("San Jose")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress1)
elem.send_keys("Googleplex, 1600 Amphitheatre Pkwy")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress2)
elem.send_keys("Mountain View, CA 94043")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpState)
elem.send_keys("California")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpZip)
elem.send_keys("94088")
time.sleep(time_sleep)
# Click on the Submit button
submit_button = driver.find_element(By.CSS_SELECTOR, cssInpButton)
submit_button.click()
time.sleep(2)
try:
element = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".success-msg"))
)
assert resultant_str in element.text, f"'{resultant_str}' not found in the specified element."
except Exception as e:
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
pytest.fail(f"Text '{resultant_str}' not found: {str(e)}")
time.sleep(2)
except Exception as e:
# Catch other exceptions
print(f"Failed: Input Form Demo, generic exception - {e}")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=passed")
print(f"PyTest Demo: Test Passed")
def teardown_method(self):
if (self.driver != None):
# self.driver.close()
self.driver.quit()
if __name__ == "__main__":
pytest.main()
Revisión del Código
Para comenzar, primero importamos los módulos necesarios requeridos para la implementación de pruebas. Dado que estamos utilizando pytest, el módulo pytest
también se importa en el código.
La clase WebDriverWait
del módulo selenium.webdriver.support.ui se importa para que podamos usar esperas explícitas en escenarios donde los WebElements se localizan dinámicamente. El módulo expected_conditions
proporciona un conjunto de ExpectedConditions predefinidas en Selenium que se pueden utilizar con esperas explícitas.
Como los elementos necesitan ser localizados antes de realizar cualquier acción, primero definimos los localizadores de elementos requeridos. ID, Nombre, XPath, Texto del Enlace, Texto del Enlace Parcial, etc., son algunos de los localizadores web ampliamente utilizados que te ayudan a encontrar elementos dentro del Modelo de Objetos del Documento (DOM).
Puedes utilizar las herramientas de inspección disponibles de forma nativa en el navegador web o un complemento (o extensión) como POM Builder que facilita encontrar el XPath/Selector CSS de los elementos web.
Una vez que se identifica el localizador web, el(los) WebElement(s) respectivo(s) se localiza(n) combinando el localizador con el método find_element()
o find_elements()
de Selenium Python. El método find_element()
devuelve un solo WebElement, mientras que find_elements()
devuelve una lista de WebElements que coinciden con los criterios del localizador.
Como se mencionó anteriormente, el setup_method()
es un fixture de pytest que forma parte de la inicialización. El método se llama antes de que se implemente cada función de prueba bajo la clase de prueba mencionada.
Las pruebas implementadas pueden ejecutarse en Selenium instalado en la máquina local así como en el grid de Selenium en línea ofrecido por pruebas en la nube. LambdaTest es una plataforma de ejecución de pruebas impulsada por IA que te permite ejecutar pruebas automatizadas en Python a escala en diferentes navegadores y sistemas operativos. Viene con varios beneficios, siendo los principales una reducción en el mantenimiento, menores costos y aceleración en la ejecución de pruebas.
En lo que respecta a la implementación, el único cambio está relacionado con Selenium WebDriver, donde Remote WebDriver en Selenium se instancia al ejecutar pruebas en una cuadrícula en la nube. El Generador de Capacidades de Automatización ayuda a generar capacidades para la combinación de pruebas destinada a ser utilizada en las pruebas.
En Selenium 4, se utilizan las opciones del navegador en lugar de las Capacidades Deseadas. Puedes consultar el blog de diferencias entre Selenium 3 y Selenium 4 para saber más sobre qué está obsoleto en Selenium 4.
Las variables de entorno LT_USERNAME
y LT_ACCESS_KEY
se pueden obtener en Configuración de Cuenta de LambdaTest > Contraseña y Seguridad. La combinación, cuando se pasa junto con la URL de la cuadrícula de LambdaTest, ayuda a ejecutar pruebas en la cuadrícula en la nube. En el método test_enter_form_details()
, primero navegamos a la URL de prueba invocando el método driver.get()
.
A continuación, se maximiza la ventana del navegador instanciada, ya que se considera una de las mejores prácticas de Selenium.
A continuación, se localiza el elemento de envío de formulario de entrada utilizando el método find_element()
junto con el localizador XPath en Selenium. Una vez localizado, se invoca el clic en el botón en Selenium para simular la acción de clic en el elemento del botón localizado en el paso anterior.
Dado que todos los pasos de prueba implican localizar elementos y realizar acciones, nos enfocamos solo en algunos métodos. El enfoque utilizado para localizar el elemento de la empresa a través del Selector CSS en Selenium se muestra a continuación. El send_keys()
en Selenium WebDriver ayuda a enviar entrada de texto en el elemento localizado.
Los menús desplegables son ampliamente utilizados en sitios web; por lo tanto, automatizar las interacciones con los menús desplegables utilizando Selenium se convierte en una necesidad absoluta para sus casos de prueba. La clase Select
del módulo selenium.webdriver.support.ui proporciona métodos que le permiten manejar los menús desplegables con Selenium.
Aquí, se crea un objeto (es decir, country_dropdown
) de la clase Select
con la entrada configurada en el elemento de menú desplegable localizado con XPath. El método select_by_visible_text()
de la clase Select
ayuda a seleccionar elementos con texto visible que coincida con la cadena proporcionada (es decir, Estados Unidos).
Una vez que se ha ingresado toda la información en el formulario y se hace clic en el botón Enviar, esperamos hasta que el mensaje de éxito (predeterminado: oculto) sea visible en la página. Se realiza una espera explícita con la ExpectedCondition (es decir, presencia del elemento localizado) hasta que el mensaje de éxito no esté en la página.
Se genera un assert si la cadena resultante no está presente en la página. Para la ejecución en la nube, la variable lambda-status
se marca como aprobado/fallido dependiendo del estado de la ejecución.
El fixture teardown_method()
contiene la implementación para limpiar los recursos o el estado después de la ejecución de las pruebas en la clase. La construcción if __name__ == "__main__":
asegura que la ejecución del código se realice solo cuando el script se ejecute directamente. El llamado a pytest.main()
llama al framework de pytest que luego descubre y ejecuta todas las pruebas habilitadas (es decir, no marcadas como omitidas) en el script.
Ejecución de pruebas (marco de trabajo pytest)
Después de configurar EXEC_PLATFORM
en la nube, invoca el siguiente comando en la terminal para ejecutar pruebas pytest en la cuadrícula de la nube de LambdaTest:
pytest --verbose --capture=no tests/pytest/pytest_selenium_demo.py
A continuación se muestra la captura de pantalla del panel de automatización web de LambdaTest que indica que la ejecución de la prueba fue exitosa:
Implementación (marco de trabajo PyUnit)
El script de prueba para el escenario de prueba mencionado anteriormente utilizando el marco de trabajo PyUnit se encuentra en tests/pyunit/pyunit_selenium_demo.py.
La lógica principal de la prueba permanece sin cambios al migrar de pytest a PyUnit (o unittest) framework. En lugar del módulo pytest
, se importa el módulo unittest
en el código. La clase de caso de prueba hereda de unittest.TestCase
informa al módulo unittest que este es un caso de prueba.
Los fixtures de pytest setup_method()
/teardown()
son similares a los métodos setUp()
/tearDown()
del marco de trabajo PyUnit. Los métodos setUp()
y tearDown()
consisten en una implementación cuya responsabilidad es la inicialización y desinicialización, respectivamente.
A continuación se muestra el código de plantilla para ejecutar la suite de pruebas:
if __name__ == "__main__":
unittest.main()
Ejecutando Pruebas (Marco PyUnit)
Después de establecer EXEC_PLATFORM
en la nube, invoca el siguiente comando en la terminal para ejecutar pruebas de PyUnit en la cuadrícula de la nube:
python tests/pyunit/pyunit_selenium_demo.py
Se muestra a continuación una captura de pantalla del panel de automatización web de LambdaTest que indica que la ejecución de la prueba fue exitosa:
En caso de que desees ejecutar las pruebas anteriores en Selenium instalado en la máquina local, simplemente establece EXEC_PLATFORM
en local, y estarás listo para la ejecución local.
Principales Marcos de Pruebas de Python
Como Python admite varios marcos de automatización de pruebas, elegir el marco adecuado se vuelve extremadamente crucial para tu proyecto. La elección realmente sienta las bases para pruebas eficientes. Además de las capacidades del marco, también necesitas tener en cuenta la experiencia interna con dicho marco. A continuación se presentan algunos de los mejores marcos de pruebas de Python:
PyUnit (unittest)
Es el marco predeterminado disponible en Python. Como su nombre indica, se utiliza principalmente para pruebas unitarias. PyUnit se inspira en el marco JUnit para Java y comparte una estructura y funcionalidad similar.
El marco de pruebas unittest también admite compartir automatización de pruebas de código de configuración e cierre para pruebas, independencia de las pruebas del marco de informes y más. También admite conjuntos de pruebas y casos de prueba de una manera orientada a objetos. También tiene un ejecutor de pruebas que es un componente responsable de orquestar la ejecución de pruebas.
pytest
Es uno de los marcos de automatización de pruebas más populares para Python. Utiliza una sintaxis menos verbosa y amigable para implementar pruebas. pytest se puede aprovechar para implementar pruebas unitarias así como pruebas funcionales complejas para probar sitios web y aplicaciones web.
Las pruebas escritas utilizando pytest son mucho más compactas, ya que el marco no requiere código redundante. pytest tiene características integradas que ayudan con el auto-descubrimiento de módulos y funciones de prueba.
Robot
Es un marco de Python de código abierto basado en palabras clave que se utiliza mayormente para Automatización de Procesos Robóticos (RPA) y automatización de pruebas. Al igual que el marco pytest, Robot es también extensible. El uso de una sintaxis/palabras clave legibles por humanos minimiza la curva de aprendizaje involucrada en aprender Robot.
Las pruebas escritas en Robot se guardan con una extensión .robot
. En caso de que planees usar Robot para pruebas front-end, puedes hacerlo con SeleniumLibrary, que es una biblioteca de pruebas web para el Framework Robot. La biblioteca admite una amplia gama de palabras clave (Click Button, Click Image, Open Browser, Drag and Drop, entre otros).
Nose2
Es el sucesor de Nose y es un marco de prueba de Python que extiende las capacidades del marco PyUnit (o unittest). Es relativamente fácil comenzar con Nose2 si tienes experiencia laboral previa con unittest.
La principal ventaja de Nose2 sobre PyUnit es la disponibilidad de una gran cantidad de complementos integrados en Nose que facilitan y aceleran las pruebas. Los complementos en Nose2 ayudan en la parametrización de pruebas, una mejor organización de las pruebas, soporte de fixtures, descubrimiento de pruebas y más.
Behave
Es un marco de Python que se utiliza para el Desarrollo Guiado por Comportamiento (BDD). Las pruebas se basan en la sintaxis de Gherkin, que se basa en el formato Dado-Cuando-Entonces.
Dado que las pruebas se implementan en escenarios y archivos de características, incluso el personal no técnico puede ser parte del proceso de QA. SpecFlow (C#) y Cucumber (Java, JS, Ruby) son algunos de los otros marcos BDD populares.
Conclusion
Hasta ahora, se ha visto que Python es, con mucho, el mejor lenguaje de script para la automatización de pruebas. Es relativamente fácil comenzar con las pruebas de automatización en Python. Su amplia gama de marcos de prueba se puede utilizar para pruebas unitarias, pruebas en varios navegadores y más. Háganos saber a continuación cuál es su lenguaje de programación preferido para las pruebas de Selenium y cómo lo califica en comparación con Python, el rey indiscutible de las pruebas de automatización. ¡Felices pruebas!
Source:
https://dzone.com/articles/python-automation-testing-with-examples