En este reto vamos a seguir trabajando con nuestra aplicación catálogo de modelos de UVL, en la que simularemos que hemos recibido una incidencia que informa de un fallo. El objetivo no es encontrar el defecto que lo ha provocado por por ensayo y error; tendremos que seguir la metodología discutida en la clase de teoría:
- estudiar el informe;
- reproducir el fallo en el entorno indicado;
- registrar evidencias e hipótesis;
- diagnosticar la causa;
- escribir una prueba de regresión;
- reparar y validar;
- dejar trazabilidad en la incidencia y en el commit.
4.1. Preparar el entorno
- Descarga o clona minireto-04-uvl-incidencia.
- Crea y activa un entorno virtual.
- Instala
pytest. - Ejecuta las pruebas actuales.
- Construye el catálogo normal.
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements-dev.txt
python3 -m pytest
python3 build.py
La batería inicial debe pasar y el catálogo normal debe construirse.
4.2. Estudiar el informe
- Abre
INCIDENCIA.md. - Identifica el comportamiento esperado y el observado.
- Anota las dos variables de entorno y los directorios que aparecen.
- Registra en
DIARIO_DEPURACION.mdqué información es esencial para reproducir el problema.
No busques todavía una línea defectuosa. Depurar con método comienza reproduciendo el comportamiento descrito, no leyendo código al azar.
4.3. Reproducir el fallo
export CATALOG_FILE=external/catalog.csv
export UVL_MODELS_DIR=external/models
python3 validate.py
El resultado defectuoso debe indicar que busca weather.uvl en models/weather.uvl, aunque se había configurado external/models.
Línea 2: no existe models/weather.uvl
Repite la ejecución para confirmar que el fallo es consistente. Guarda el mensaje como evidencia.
4.4. Formular y comprobar una hipótesis
La primera hipótesis razonable es que la aplicación lee CATALOG_FILE, pero ignora UVL_MODELS_DIR.
- Busca dónde se consulta
CATALOG_FILE. - Busca la función
get_models_dir(). - Compara ambas implementaciones.
Encontrarás:
def get_models_dir() -> Path:
return Path("models")
La función contiene una ruta fija. Esto explica por qué el resultado observado menciona models/weather.uvl.
4.5. Escribir una prueba de regresión
Antes de reparar, crea tests/test_environment.py:
from pathlib import Path
from catalog import get_models_dir
def test_models_directory_can_be_configured(monkeypatch, tmp_path: Path):
monkeypatch.setenv("UVL_MODELS_DIR", str(tmp_path))
assert get_models_dir() == tmp_path
Ejecuta solo esa prueba:
python -m pytest tests/test_environment.py -q
Debe fallar. La fixture monkeypatch permite modificar temporalmente el entorno y lo restaura al terminar. tmp_path proporciona un directorio temporal aislado para la prueba.
La prueba convierte el informe de incidencia en una especificación ejecutable. Si el defecto reaparece en el futuro, la batería lo detectará.
4.6. Reparar la causa raíz
Modifica get_models_dir() para que use la variable de entorno y conserve models como valor predeterminado:
def get_models_dir() -> Path:
return Path(os.environ.get("UVL_MODELS_DIR", "models"))
4.7. Validar la reparación
- Ejecuta la prueba de regresión.
- Ejecuta toda la batería.
- Repite exactamente los pasos de reproducción del informe.
- Elimina las variables o abre una terminal nueva y comprueba que el catálogo normal sigue funcionando.
python -m pytest -q
python validate.py
Con las variables configuradas, validate.py debe imprimir El catálogo es válido. Sin ellas, debe seguir utilizando catalog.csv y models.
4.8. Dejar trazabilidad
En la incidencia registra:
- cómo se reprodujo el fallo;
- la causa raíz;
- la prueba de regresión añadida;
- el resultado de la batería;
- la referencia al commit que contiene la corrección.
Un mensaje de commit razonable sería:
Respeta UVL_MODELS_DIR al localizar los modelos
Fixes #<número-de-incidencia>
Cerrar una incidencia no consiste solo en cambiar una línea. La organización debe poder reconstruir qué ocurrió, cómo se comprobó y qué evidencia evita la regresión.