La creación de un framework de pruebas puede abordarse desde dos perspectivas principales: un enfoque ascendente (bottom-up) o un enfoque descendente (top-down). El método ascandente, que comienza con scripts básicos y los evoluciona hacia una estructura de framework, es ideal para quienes se inician y desean comprender la progresión. En contraste, el enfoque descendente implica el diseño directo de la arquitectura del framework y la selección de soluciones a problemas específicos, siendo más adecuado para profesionales con experiencia significativa en la implementación de frameworks. Este capítulo se centrará en el proceso de construcción utilizando el enfoque ascendente.
De Scripts a Casos de Prueba Estructurados
A diferencia de una colección desorganizada de scripts, la utilización de un formato estandarizado para los casos de prueba facilita una ejecución y gestión más flexibles. Un caso de prueba de automatización completo debe incorporar los siguientes componentes:
- Preparación (Setup): Pasos de configuraicón iniciales, métodos auxiliares o herramientas necesarias. Pueden ser compartidos entre múltiples pruebas.
- Pasos de Prueba (Test Steps): Las acciones fundamentales que constituyen el escenario de prueba.
- Aserciones (Assertions): Verificaciones donde el resultado esperado se compara con el resultado actual. Un solo caso puede incluir varias aserciones.
- Limpieza (Teardown): Acciones para revertir cualquier cambio realizado durante la ejecución de la prueba, asegurando que no afecte a pruebas posteriores. También pueden ser compartidos.
Transformando Scripts en Funciones de Prueba
Convertir un script de prueba en un caso de prueba Pytest es un proceso sencillo. Simplemente, encapsulamos el proceso de prueba dentro de una función cuyo nombre comienza con test_.
A menudo, para una implementación rápida, escribimos el código directamente en un módulo, siguiendo una secuencia de pasos. Por ejemplo, el siguiente script realiza una búsqueda en Google:
Contenido del archivo buscador_web_v0.9.py:
from selenium import webdriver
import time
controlador = webdriver.Chrome()
controlador.get("https://www.google.com")
controlador.find_element("id", "APjFqb").send_keys("automatizacion web python") # ID del campo de búsqueda de Google
controlador.find_element("name", "btnK").click() # Botón de búsqueda
time.sleep(2)
if "automatizacion web" in controlador.title:
print("Prueba exitosa")
else:
print("Prueba fallida")
controlador.quit()
Para la primera optimización, podemos organizar los pasos en una función, lo que permite múltiples casos de prueba en un solo archivo. Además, adoptaremos el estilo de escritura de Pytest, utilizando aserciones estándar para verificar los resultados esperados. La versión modificada sería la siguiente:
Contenido del archivo buscador_web_v1.0.py:
from selenium import webdriver
import time
def test_busqueda_google_exito():
navegador = webdriver.Chrome()
navegador.get("https://www.google.com")
campo_busqueda = navegador.find_element("id", "APjFqb")
campo_busqueda.send_keys("framework de pruebas con selenium")
boton_busqueda = navegador.find_element("name", "btnK")
boton_busqueda.click()
time.sleep(2)
assert "framework de pruebas" in navegador.title, "El título de la página no contiene la frase esperada."
navegador.quit()
A diferencia de la versión 0.9, que se ejecuta como un script Python normal (python <ruta_script>), los scripts de Pytest se ejecutan usando pytest <ruta_script> o python -m pytest <ruta_script>. También es posible añadir el siguiente bloque al final del script de Pytest:
if __name__ == '__main__':
import pytest
pytest.main([__file__])
Esto permite ejecutar el archivo directamente como un script Python. __file__ se refiere al script actual, y se pueden añadir otros parámetros de ejecución, como -qs.
Implementación de Aserciones
Es crucial que los casos de prueba contengan verificaciones de resultados esperados para determinar su éxito o fracaso. A diferencia de la "depuración", que a menudo requiere supervisión manual para validar cada paso, las "pruebas" automatizadas necesitan ejecutarse en lotes y auto-validar los resultados. Las aserciones son el mecanismo para comparar automáticamente los resultados reales con los esperados durante la ejecución.
Pytest utiliza las sentencias assert estándar de Python para las aserciones. Cuando una aserción falla (el rseultado real no coincide con el esperado), se lanza una excepción AssertionError. El framework de pruebas captura automáticamente esta excepción, marca el caso de prueba como fallido y, crucialmente, no detiene la ejecución de otras pruebas debido a la excepción.
Nota: También es posible marcar un caso de prueba como fallido utilizando una condición
ifcombinada conpytest.fail()o lanzando manualmente unAssertionError. Por ejemplo:
if 'resultado esperado' not in navegador.title:
# raise AssertionError('Mensaje de fallo personalizado')
pytest.fail('El título no incluye la frase esperada después de la operación.')
En las pruebas de automatización de interfaz de usuario web, algunas estrategias de aserción comunes incluyen:
- Éxito del flujo de ejecución: Se considera un éxito si todos los pasos de interacción con los elementos se completan sin errores.
- Aserción por título de página: Se verifica el título actual de la página (
driver.title) para confirmar que se está en la página correcta. - Aserción por URL: Se compara la URL actual (
driver.current_url) para determinar la ubicación en el sitio. - Aserción por código fuente de la página: Se busca la presencia de información específica en el código fuente de la página (
driver.page_source). - Aserción por existencia de elementos: Se comprueba la presencia de un elemento específico en la página para validar su estado o ubicación.
Un ejemplo de cómo verificar la presencia de un elemento para confirmar que se está en una página específica:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import pytest
def test_abrir_pagina_principal():
control_web = webdriver.Chrome()
control_web.get("https://www.google.com")
try:
control_web.find_element("id", "APjFqb") # Intenta localizar el campo de búsqueda
print("Campo de búsqueda encontrado, página principal de Google cargada.")
except NoSuchElementException:
pytest.fail('El campo de búsqueda no está presente, indicando que no se cargó la página correcta.')
finally:
control_web.quit()
Dentro de un framework, los métodos de aserción de uso frecuente pueden encapsularse para simplificar su invocación y mejorar la legibilidad.