pytest: Framework de pruebas unitarias para Python

pytest es un framework de pruebas unitarias de terceros para Python, reconocido por su simplicidad y eficiencia en comparación con el módulo unittest incorporado. Ofrece compatibilidad con más de 315 plugins y permite integrar unittest sin necesidad de reescribir código existente, facilitando transiciones entre frameworks.

Configuración del entorno

Para instalar pytest y componentes relacionados, se utilizan comandos de pip:

pip install pytest
pip install pytest-html  # Plantilla para reportes
pip show pytest  # Verificar instalación

Reglas para ejecutar pruebas

  • Los archivos de prueba deben iniciar con test_ o terminar con _test.
  • Las clases de prueba deben iniciar con Test y no contener métodos __init__.
  • Los métodos de prueba deben iniciar con test.
  • Las aserciones se realizan con la palabra clave assert.

Funciones de configuración y limpieza

pytest soporta múltiples niveles de configuración y limpieza:

  • setup_module y teardown_module: Ejecutan una vez antes y después de todas las pruebas en un módulo.
  • setup_class y teardown_class: Ejecutan antes y después de todas las pruebas dentro de una clase.
  • setup_method y teardown_method: Ejecutan antes y después de cada método de prueba en una clase.
  • setup_function y teardown_function: Ejecutan antes y después de cada función de prueba fuera de clases.

Pruebas basadas en datos

La funcionalidad @pytest.mark.parametrize permite ejecutar pruebas con múltiples conjuntos de datos:

import pytest

@pytest.mark.parametrize("operando_a, operando_b, suma_esperada", [(15, 25, 40), (30, 10, 40)])
def test_calculo_suma(operando_a, operando_b, suma_esperada):
    resultado = operando_a + operando_b
    assert resultado == suma_esperada

Uso de fixtures

Los fixtures son funciones decoradas con @pytest.fixture que proporcionan datos o configuraciones a las pruebas. Su firma incluye parámetros como:

  • scope: Define el ámbito (function, class, module, session).
  • params: Lista de parámetros para pruebas parametrizadas.
  • autouse: Si es True, se aplica automáticamente a todas las pruebas.
  • ids: Identificadores personalizados para los parámetros.
  • name: Nombre alternativo del fixture.

Alcance de fixtures

El alcance determina la frecuencia de ejecución:

  • function: Por cada función o método de prueba.
  • class: Por cada clase de prueba.
  • module: Por cada módulo Python (archivo .py).
  • session: Una vez por sesión de pruebas, compartido entre múltiples módulos.

Aplicación de fixtures

Existen tres métodos principales para usar fixtures:

# 1. Pasar el fixture como parámetro en la función de prueba
@pytest.fixture()
def preparar_datos():
    print("Configuración inicial")
    return {"id": 101, "valor": 50}

def test_validar_datos(preparar_datos):
    assert preparar_datos["valor"] > 0

# 2. Usar el decorador @pytest.mark.usefixtures
@pytest.fixture()
def inicializar_entorno():
    print("Entorno listo")

@pytest.mark.usefixtures("inicializar_entorno")
def test_operacion():
    print("Ejecutando operación")

# 3. Combinar múltiples fixtures con @pytest.mark.usefixtures
@pytest.fixture()
def configurar_red():
    print("Red configurada")

@pytest.fixture()
def cargar_config():
    print("Configuración cargada")

@pytest.mark.usefixtures("configurar_red")
@pytest.mark.usefixtures("cargar_config")
def test_conexion():
    print("Prueba de conexión completada")

Ejecución con pytest.main

La función pytest.main inicia el runner de pruebas. Parámetros comunes:

  • -m "marca": Ejecuta pruebas con una marca específica.
  • -k "expresión": Filtra pruebas por nombre usando expresiones lógicas.
  • -s: Muestra salidas estándar en la consola.
  • -v: Modo detallado con información extendida.
  • --collect-only: Lista pruebas sin ejecutarlas.
  • --ignore=ruta: Excluye módulos de prueba.
  • -q: Reduce la verbosidad de la salida.
  • -x: Detiene la ejecución tras el primer fallo.

Omisión de pruebas

Se pueden omitir pruebas usando decoradores como @pytest.mark.skip para omisión incondicional o @pytest.mark.skipif para omisión basada en condiciones.

Integración con Allure para reportes

Allure mejora los reportes mediante decoradores específicos:

  • @allure.epic(): Define un épico en metodologías ágiles.
  • @allure.feature(): Describe un módulo o funcionalidad.
  • @allure.story(): Especifica una historia de usuario.
  • @allure.title(): Asigna un título a la prueba en el reporte.
  • @allure.severity(): Establece niveles como blocker, criticla, normal, minor o trivial.
  • @allure.step(): Documenta pasos dentro de una prueba.
  • @allure.attachment(): Adjunta archivos al reporte.

Etiquetas: pytest python-testing pytest-fixtures pytest-parametrize allure-reports

Publicado el 6-16 05:31