Uso Básico del Framework de Pruebas Pytest

pytest es un framework de pruebas maduro y completo para Python, reconocido por su flexibilidad y facilidad de uso. Entre sus características destacan:

  • Documentación abundante y curva de arpendizaje suave.
  • Soporte para parametrización que permite control detallado de casos de prueba.
  • Idóneo para pruebas unitarias simples y funcionales complejas, así como para automatización con herramientas como Selenium o para APIs.
  • Amplia gama de plugins de terceros, como pytest-selenium, pytest-html y otros.
  • Gestión de pruebas omitidas o marcadas como xfail.
  • Integración sencilla con sistemas de CI como Jenkins.

Convenciones de escritura:

  • Archivos de prueba deben iniciar con test_ o terminar con _test.
  • Clases de prueba empiezan con Test y no deben definir el método __init__.
  • Funciones de prueba deben iniciar con test_.
  • Las aserciones se realizan con la palabra clave assert.

Ejemplo Inicial

Archivo: ejemplo_pruebas.py


import pytest

class CasosDePrueba:
    def test_cadena_contiene_letra(self):
        texto = "ejemplo"
        assert 'p' in texto

    def test_atributo_disponible(self):
        datos = "mundo"
        assert hasattr(datos, 'split')

    def test_subcadena_presente(self):
        sub = "hola"
        cadena = "hola python"
        assert sub in cadena

Ejecución desde terminal:


cd al_directorio
pytest ejemplo_pruebas.py

Para visualizar una barra de progreso, instale el plugin pytest-sugar.

Configuración en PyCharm:

  1. Acceda a File -> Settings -> Tools -> Python Integrated Tools.
  2. Seleccione el nombre del proyecto y cambie Default test runner a pytest.

Ejecución programática:


if __name__ == "__main__":
    pytest.main(['-q', 'ejemplo_pruebas.py'])

Parámetros de Consola

  • -v: Muestra resultados detallados por función.
  • -q: Presenta solo el resumen global.
  • -s: Muestra salidas de print() en pruebas.
  • -x: Detiene en el primer fallo.
  • -m: Filtra pruebas por decoradores.
  • -h: Muestra ayuda.

Ejemplos de comandos:


pytest  # Ejecuta todas las pruebas en el directorio
pytest modulo.py  # Ejecuta pruebas en el archivo
pytest -k "expresion"  # Filtra por nombre
pytest modulo.py::funcion  # Ejecuta prueba específica

Parametrización

Uso de @pytest.mark.parametrize():

Parámetro individual:


import pytest
import random

@pytest.mark.parametrize('entrada', [7, 14, 21])
def test_comparar_valor(entrada):
    aleatorio = random.randint(1, 30)
    assert entrada != aleatorio

Múltiples parámetros:


import pytest

@pytest.mark.parametrize('x, y, resultado', [
    (2, 2, 4),
    (5, 3, 8),
    ("a", "b", "ab"),
])
def test_operacion(x, y, resultado):
    if isinstance(x, str):
        res = x + y
    else:
        res = x + y
    assert res == resultado

Orden de Ejecución

Instale pytest-ordering:


pip install pytest-ordering

Controle el orden con @pytest.mark.run(order=n):


import pytest

global_estado = []

@pytest.mark.run(order=2)
def test_segunda_etapa():
    global_estado.append("segundo")
    assert len(global_estado) == 2

@pytest.mark.run(order=1)
def test_primera_etapa():
    global_estado.append("primero")
    assert global_estado[0] == "primero"

Reportes HTML

Instale pytest-html:


pip install -U pytest-html

Generación de reporte:


pytest ejemplo_pruebas.py --html=informe.html

Cobertura de Código

Instale pytest-cov:


pip install pytest-cov

Uso:


pytest --cov-report=html --cov=./ src_pruebas

Parámetros relevantes:

  • --cov=[ruta]: Define la ruta para medir cobertura.
  • --cov-report=tipo: Formato del reporte (html, xml, etc.).
  • --no-cov-on-fail: Omite reporte si hay fallos.
  • --cov-fail-under=MIN: Exige un mínimo de cobertura.

Ejecución Paralela

Instale pytest-xdist:


pip install -U pytest-xdist

Ejecución con múltiples procesos:


pytest ejemplo_pruebas.py -n 4  # Usa 4 procesos

Reintentos de Pruebas Fallidas

Instale pytest-rerunfailures:


pip install pytest-rerunfailures

Ejemplo con posible fallo:


import random

def dividir(a, b):
    return a / b

def test_division_segura():
    divisor = random.choice([1, 2, 0])
    if divisor == 0:
        pytest.skip("Evitar división por cero")
    assert dividir(10, divisor) > 0

Uso desde consola:


pytest --reruns 2  # Reintenta dos veces
pytest --reruns 2 --reruns-delay 3  # Con 3 segundos de pausa

Alternativamente, use el decorador @pytest.mark.flaky(reruns=2, reruns_delay=3).

Etiquetas: pytest Python automatización de pruebas parametrizacion informes HTML

Publicado el 7-23 06:02