第二班Grupo 2Calidad de Software · 2026-B8 min · 10 escenas

POV: 588 pruebas en verde… y aun así faltaba una

Caja blanca ×
Integración

Técnica: pruebas de caja blanca · Tipo: pruebas de integración · Caso real: OLA, nuestro sistema de alertas térmicas del litoral peruano (FastAPI + PostgreSQL), con capturas de ejecución reales.

    Universidad La Salle · Arequipa · Docente: Maribel Molina Barriga · noviembre de 2026

    Rueda del mouse o ↓ · N guion · F pantalla completa · C confeti · doble clic
    02 · 概念Marco conceptual ITL;DR: probar mirando el código por dentro

    Pruebas de caja blanca

    Abre la caja → mira el código por dentro

    Definición

    Técnica que deriva los casos de prueba de la estructura interna del componente: sentencias, decisiones, condiciones y caminos. También se llama prueba estructural o de caja de cristal.

    ISTQB (2023); ISO (2021)

    Objetivo

    Ejecutar cada camino lógico relevante para encontrar lógica errónea, ramas olvidadas y código muerto, y medir con un criterio objetivo cuánto código ejercitó la suite.

    Myers et al. (2011); Pressman y Maxim (2020)

    Relevancia en el aseguramiento de la calidad

    Convierte «ya probamos» en un número verificable (la cobertura) que sirve como criterio de salida en la integración continua. Complementa a la caja negra: una mira qué hace el sistema y la otra cómo lo hace.

    ISTQB (2023); Ammann y Offutt (2017)
    V(G) = E − N + 2 = P + 1

    Complejidad ciclomática (McCabe, 1976): número de caminos independientes = mínimo de casos para cubrirlos. E aristas, N nodos, P decisiones.

    03 · 概念Marco conceptual IITL;DR: probar que las piezas funcionan juntas

    Pruebas de integración

    Cada pieza funciona sola… ¿y juntas?

    Definición

    Nivel de prueba centrado en las interacciones entre componentes o sistemas: interfaces, contratos, datos que viajan entre módulos, transacciones y configuración. Se distingue entre la integración de componentes y la de sistemas.

    ISTQB (2023); Sommerville (2016)

    Objetivo

    Encontrar los defectos de interfaz que las pruebas unitarias no ven: formatos, códigos HTTP, consultas a la base de datos, transacciones y configuración del entorno.

    Myers et al. (2011); Vocke (2018)

    Relevancia

    Es donde salen los defectos «de entorno»: en OLA, 4 de los 33 defectos registrados se detectaron aquí, tres en la importación del CSV, donde el código toca archivos y base de datos.

    docs/defectos.md del proyecto

    Estrategias de integración elige una

    pytest + TestClient (driver) API · router + JWT Servicio de avisos Servicio de importación Correo (SMTP) Repositorios PostgreSQL 17

    DriverInvoca al módulo bajo prueba. En OLA: TestClient.
    StubReemplaza a un módulo invocado con respuestas fijas. En OLA: users_repo en 2 pruebas.
    Mock / spyVerifican cómo fue invocado; el spy registra las llamadas. En OLA: RecordingMailer.
    FakeVersión ligera que sí funciona (p. ej., BD en memoria). OLA usa PostgreSQL real.
    04 · 手順Procedimiento o metodologíaTL;DR: grafo → caminos → casos → BD real → cobertura

    Procedimiento en 7 pasos

    Speedrun en 7 pasos

    05 · 道具Herramientas y entornosTL;DR: ejecutor + cobertura + BD real + CI

    Herramientas recomendadas

    Gacha de herramientas

    Equivalentes en otros entornos

    JavaJUnit 5JaCoCoMockitoTestcontainersPIT
    JS / TSJest / VitestIstanbul / V8Supertest
    API y contratosPostman + NewmanREST AssuredWireMockPact
    CalidadSonarQubeJenkins / GitLab CIJMeter (API bajo carga)
    06 · 実例Ejemplo práctico I · diseñoTL;DR: 2 decisiones → V(G) = 3 → 3 casos

    Caso: marcar un aviso como leído

    Elegimos una función real de OLA

    REALOLA en ejecución local: mapa del estado del mar con 8 zonas en alerta
    Sistema bajo prueba: OLA en local (Docker), datos reales de IMARPE.
    REALSwagger de OLA: POST /api/notifications/{notification_id}/read, respuestas 204 y 422
    Interfaz bajo prueba: POST /api/notifications/{id}/read (OpenAPI).
    router + JWT→mark_read→repositorio→PostgreSQL
    backend/src/ola/services/notification_service.pyL107–116
    def mark_read( session: Session, notification_id: int, user_id: int, *, clock: Clock | None = None) -> bool: notificacion = notifications_repo.get_for_user(session, notification_id, user_id) if notificacion is None: return False if notificacion.read_at is None: notificacion.read_at = (clock or SystemClock()).now() session.commit() return True

    Quiz: ¿cuántos casos necesitas, como mínimo, para recorrer todos los caminos independientes?

    すごい! Dos decisiones (líneas 111 y 113) → P + 1 = 3 caminos independientes.

    7 − 6 + 2E − N + 2
    2 + 1P + 1
    R1 R2 R3regiones

    Las tres fórmulas coinciden: V(G) = 3. Si se cuentan condiciones, el or de la línea 114 sumaría 1 (ver escena 9).

    07 · 実行Ejemplo práctico II · ejecuciónTL;DR: el camino 3 no tenía prueba

    De caminos a pruebas de integración

    3 caminos → 3 casos. ¿Los tenemos todos?

    camino elegidosin pruebacubierto
    CSV de muestra→import_service→POST /api/subscriptions→alert_service→create_for_events→avisos en ola_test+RecordingMailer
    tests/integration/test_notifications.py · prueba nuevapytest
    def test_marcar_dos_veces_no_cambia_la_fecha_de_lectura( self, client, db_session, con_alerta, user_headers): """Camino 3 de mark_read: el aviso ya estaba leido (rama 113 -> 116).""" aviso = client.get("/api/notifications", headers=user_headers).json()["items"][0] url = f"/api/notifications/{aviso['id']}/read" assert client.post(url, headers=user_headers).status_code == 204 db_session.expire_all() primera = db_session.get(Notification, aviso["id"]).read_at assert primera is not None assert client.post(url, headers=user_headers).status_code == 204 db_session.expire_all() assert db_session.get(Notification, aviso["id"]).read_at == primera
    REALTerminal: pytest -vv -k marcar, 4 pruebas de integración PASSED, incluida la nueva del camino 3
    Ejecución real en el contenedor api contra PostgreSQL: 4 de 4 en verde (copia de trabajo con la prueba nueva, 1/11/2026).
    合格
    08 · 結果Resultados y análisisTL;DR: ramas de 92 % a 100 % con 1 prueba

    Resultados obtenidos

    Plot twist: 100 % de líneas ≠ 100 % de ramas

    coverage.py antes: notification_service.py 98 %, línea 113 en amarillo con 113 ↛ 116
    coverage.py después: notification_service.py 100 %, línea 113 en verde
    ANTES · 98 % · 113 ↛ 116DESPUÉS · 100 %
    ANTESTerminal antes: 34 passed, notification_service.py 98 %, Missing 113->116
    34 pruebas en verde · 0 líneas sin ejecutar · 1 rama parcial
    DESPUÉSTerminal después: 35 passed, TOTAL 100 %
    35 pruebas en verde · 100 % de sentencias y ramas
    94.9 %sentencias (C0): 2395 de 2525
    87.7 %ramas (C1): 314 de 358 · 20 parciales

    C0 al 100 % no es C1 al 100 %. Dos servicios con todas sus líneas ejecutadas tenían ramas sin recorrer: 113→116 en avisos y 50→exit en la importación (nunca se probó un CSV con más de 50 errores).

    Contrato incompleto. El OpenAPI declara 204 y 422, pero el camino ① responde 404: un cliente generado desde el contrato no lo conocería.

    Los dobles dejan huecos. mail.py llega a 61 %: el SMTP real se reemplaza por RecordingMailer; lo cubren las E2E con Mailpit.

    Historial del proyecto: la integración detectó 4 de 33 defectos, 2 de severidad alta: D-02 (una fecha repetida abortaba la importación) y D-31 (la base de datos de pruebas no recibía los cambios de esquema).

    09 · 結論ConclusionesTL;DR: mide, pero piensa

    Lo que nos llevamos

    Bento de aprendizajes

    Aprendizajes y beneficios

    • Criterio medible: V(G) fija el mínimo de casos (3) y la cobertura de ramas confirma que se ejecutaron.
    • Prueba lo que de verdad se integra: API, autenticación, servicio, repositorio y PostgreSQL juntos; así aparecieron D-02, D-03, D-04 y D-31.
    • Encuentra huecos invisibles: 588 pruebas en verde y el servicio con 100 % de líneas, pero el camino ③ nunca se había ejecutado.
    • Se automatiza: en la CI se convierte en una red de regresión con un umbral mínimo (hoy, 80 % de sentencias).

    Limitaciones y consideraciones

    • Cobertura ≠ calidad: no detecta requisitos omitidos ni código que falta; las pruebas muestran la presencia de defectos, no su ausencia (ISTQB, 2023).
    • Ramas ≠ condiciones ≠ caminos: coverage.py no ve la decisión escondida en clock or SystemClock(), y con bucles los caminos explotan.
    • Cuesta más: necesita una base de datos aislada y datos controlados; solo el archivo de avisos (34 pruebas) tarda 13.5 s.
    • Acoplada al código: si la implementación cambia, el grafo y los casos se rehacen; y los dobles dejan sin probar los adaptadores reales.

    Siguientes pasos: incorporar al repositorio la prueba del camino ③ · activar --cov-branch en la CI, que hoy solo mide sentencias · probar una importación con más de 50 errores (rama 50→exit) · declarar el 404 en el contrato OpenAPI · sumar pruebas de condición (C2) y de mutación a los servicios.

    10 · 参考文献Referencias bibliográficasAPA 7.ª edición

    Referencias

    Fuentes o no pasó

    1. Ammann, P., y Offutt, J. (2017). Introduction to software testing (2.ª ed.). Cambridge University Press. https://doi.org/10.1017/9781316771273
    2. Batchelder, N. (s. f.). Branch coverage measurement. Coverage.py. Recuperado el 1 de noviembre de 2026, de https://coverage.readthedocs.io/en/latest/branch.html
    3. International Organization for Standardization. (2021). Software and systems engineering — Software testing — Part 4: Test techniques (ISO/IEC/IEEE 29119-4:2021). https://www.iso.org/standard/79430.html
    4. International Software Testing Qualifications Board. (2023). Certified Tester Foundation Level (CTFL) syllabus (versión 4.0). https://istqb.org/certifications/certified-tester-foundation-level-ctfl-v4-0/
    5. McCabe, T. J. (1976). A complexity measure. IEEE Transactions on Software Engineering, SE-2(4), 308–320. https://doi.org/10.1109/TSE.1976.233837
    6. Myers, G. J., Sandler, C., y Badgett, T. (2011). The art of software testing (3.ª ed.). John Wiley & Sons.
    7. Pressman, R. S., y Maxim, B. R. (2020). Software engineering: A practitioner's approach (9.ª ed.). McGraw-Hill Education.
    8. Sommerville, I. (2016). Software engineering (10.ª ed.). Pearson.
    9. Vocke, H. (2018, 26 de febrero). The practical test pyramid. martinfowler.com. https://martinfowler.com/articles/practical-test-pyramid.html
    ありがとう
    ¡Gracias!

    ¿Preguntas? 質問はありますか?

    Evidencia: capturas tomadas el 1/11/2026 sobre el repositorio de OLA en Docker (pytest 9.1 · coverage.py 7.16 · PostgreSQL 17).

    Grupo 2
    @grupo2.calidad· Calidad de Software 2026-B