2.13. Ingeniería de Software (SE)

2.13. Ingeniería de Software (SE)

Ya a principios de la década de 1970, el informático británico Brian Randell supuestamente dijo: "La ingeniería de software es la construcción multi-persona de programas multi-versión". Esta es una visión esencial: mientras que la programación es la habilidad que gobierna nuestra capacidad para escribir un programa, la ingeniería de software es distinta en dos dimensiones: tiempo y personas.

Primero, un proyecto de ingeniería de software es un esfuerzo de equipo; ser un experto en programación solitario es insuficiente. Los ingenieros de software calificados deben demostrar experiencia en comunicación y colaboración. La programación puede ser una actividad individual, pero la ingeniería de software es colaborativa, profundamente ligada a cuestiones de profesionalismo, trabajo en equipo y comunicación.

Segundo, un proyecto de ingeniería de software suele ser "multi-versión". Tiene una vida útil esperada; necesita funcionar correctamente durante meses, años o décadas. Las funcionalidades pueden agregarse o eliminarse para cumplir con los requisitos del producto. El propio equipo de ingeniería probablemente cambiará. El contexto tecnológico cambiará, a medida que evolucionen nuestras plataformas informáticas, cambien los lenguajes de programación, se actualicen las dependencias, etc. Esta exposición a cuestiones de tiempo y cambio es novedosa en comparación con un proyecto de programación: no basta con construir algo que funcione; debe funcionar y seguir funcionando. Muchos de los temas más desafiantes en tecnología comparten "el tiempo conducirá al cambio" como causa raíz: compatibilidad con versiones anteriores, desfase de versiones, gestión de dependencias, cambios de esquema, evolución de protocolos.

La ingeniería de software presenta un desafío particularmente difícil para el aprendizaje en un entorno académico. Dado que las principales diferencias entre la programación y la ingeniería de software son el tiempo y el trabajo en equipo, es difícil generar lecciones que requieran un trabajo en equipo exitoso y que presenten fielmente los desafíos del tiempo. Además, algunos temas de ingeniería de software serán más auténticos y relevantes si nuestros estudiantes experimentan proyectos colaborativos y a largo plazo in vivo en lugar de en el aula. Independientemente de que esto suceda como una pasantía, la participación en un proyecto de código abierto o un rol de ingeniería a tiempo completo, un mes de experiencia práctica a tiempo completo tiene más horas disponibles que el curso promedio de ingeniería de software.

Por lo tanto, un plan de estudios de ingeniería de software debe centrarse en los conceptos necesarios para la mayoría de los nuevos contratados graduados, y que son novedosos para aquellos que se capacitan principalmente como programadores, o que son conceptos abstractos que pueden no declararse/compartirse explícitamente en el trabajo. Tales temas incluyen, entre otros:

  • Pruebas
  • Trabajo en equipo, colaboración
  • Comunicación
  • Diseño
  • Mantenimiento y evolución
  • Herramientas de ingeniería de software

Todas las pruebas sugieren que el papel del software en nuestra sociedad seguirá creciendo en el futuro previsible. Además, la era de "dos programadores en un garaje" parece haber llegado a su fin. La mayoría del software importante hoy en día es un esfuerzo de equipo, que se basa en código existente y aprovecha la funcionalidad existente. El estudio de las habilidades de ingeniería de software es un contrapunto profundamente importante a la experiencia cotidiana de los estudiantes de informática: debemos impresionarles con la realidad de que pocos proyectos de software se gestionan escribiendo desde cero como un esfuerzo en solitario. La comunicación, el trabajo en equipo, la planificación, las pruebas y las herramientas son mucho más importantes a medida que nuestros estudiantes pasan del aula y dejan su huella en el mundo.

Aunque la mayoría de los graduados en CS ocuparán un puesto en la industria que requiere este material, los temas del CS Core presentados aquí son valiosos independientemente de si los graduados van a la industria o a la academia.

Tabla 2.13: Lista de KUs del área de Ingeniería de Software.

2.13.1. SE/Colaboración y Dinámica de Equipo  (CS Core: 2 hrs, KA Core: 2 hrs) ↑ Volver arriba

Temas:
Core

Aprendizaje esperado (Learning Outcomes):
Core:

  1. Seguir prácticas efectivas de comunicación en equipo [Analizar]
  2. Articular las fuentes, peligros y beneficios potenciales del conflicto en el equipo, especialmente enfocándose en el valor de estar en desacuerdo sobre ideas o propuestas sin insultar a las personas [Articular]
  3. Facilitar una estrategia de resolución de conflictos y resolución de problemas en un entorno de equipo [Analizar]
  4. Colaborar efectivamente en desarrollo/programación cooperativa [Analizar]
  5. Proponer y delegar los roles y responsabilidades necesarios en un equipo de desarrollo de software [Proponer]
  6. Redactar y seguir una agenda para una reunión de equipo [Componer]
  7. Facilitar, a través de la participación en un proyecto de equipo, los elementos centrales de la formación de equipos, el establecimiento de una cultura de equipo saludable y la gestión de equipos, incluida la creación y ejecución de un plan de trabajo del equipo [Crear]

2.13.2. SE/Diversidad, Stakeholders y Equipos Distribuidos  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

Temas:
Core

  • Importancia de la diversidad e inclusión en el equipo. Comunicación Técnica y Profesional , Comunicación en Equipo y Cultura
  • Interfaz con las partes interesadas, como equipo:
    1. Gestión y otros equipos no técnicos
    2. Clientes
    3. Usuarios enumerate
    4. Riesgos asociados con equipos físicos, distribuidos, híbridos y virtuales, incluyendo comunicación, percepción, estructura, puntos de falla, mitigación y recuperación, etc.

    Aprendizaje esperado (Learning Outcomes):
    Core:

    1. Promover la importancia y los beneficios que la diversidad y la inclusión aportan a un equipo de desarrollo de software [Defender]
    2. Referenciar, como equipo, la importancia de, y las estrategias para interactuar con partes interesadas fuera del equipo en niveles tanto técnicos como no técnicos [Referenciar]
    3. Enumerar los riesgos asociados con equipos físicos, distribuidos, híbridos y virtuales y los posibles puntos de falla y cómo mitigarlos y recuperarse/aprender de los fallos [Enumerar]

    2.13.3. SE/Control de Versiones y CI/CD  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

    Temas:
    Core

    • Gestión de configuración de software y control de versiones: Prácticas de Desarrollo de Software
      1. Configuración en control de versiones, builds/configuración reproducibles.
      2. Estrategias de ramificación en control de versiones. Ramas de desarrollo vs ramas de lanzamiento. Desarrollo basado en tronco (trunk-based development).
      3. Estrategias de fusión/rebase, cuando sean relevantes. enumerate
      4. Gestión de lanzamientos (release management).
      5. Herramientas de prueba, incluyendo herramientas de análisis estático y dinámico. Prácticas de Desarrollo de Software , Flujo de Información y No Interferencia , Inyección y Validación de Entrada , Seguridad de Memoria y Tipos , Análisis de Malware y Seguridad Avanzada
      6. Automatización de procesos de software:
        1. Sistemas de construcción (build systems): el valor de builds rápidos, herméticos y reproducibles, comparar/contrastar enfoques para construir un proyecto.
        2. Integración Continua (CI): el uso de automatización y pruebas automatizadas para hacer una validación preliminar de que la revisión actual del tronco se construye y pasa las pruebas (básicas).
        3. Despliegue Continuo (CD): el uso de automatización para liberar de forma automática cada cambio que supera las pruebas hacia el entorno de producción, garantizando entregas frecuentes y confiables.
        4. Gestión de dependencias: actualización de dependencias externas/aguas arriba, gestión de paquetes, SemVer. enumerate

        Aprendizaje esperado (Learning Outcomes):
        Core:

        1. Describir la diferencia entre la gestión de configuración de software centralizada y distribuida [Describir]
        2. Describir cómo el control de versiones puede usarse para ayudar en la gestión de lanzamientos de software [Describir]
        3. Identificar elementos de configuración y usar una herramienta de control de código fuente en un proyecto pequeño basado en equipo [Analizar]
        4. Describir cómo las herramientas de prueba estáticas y dinámicas disponibles pueden integrarse en el entorno de desarrollo de software [Describir]
        5. Comprender el uso de sistemas de CI/CD como una fuente de verdad para el estado del código compartido del equipo (éxito en la construcción y pruebas) [Explicar]

        2.13.4. SE/Entorno de Desarrollo e IDE  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

        Temas:
        Core

        • Herramientas de diseño y comunicación (documentos, diagramas, formas comunes de diagramas de diseño como UML).
        • Conceptos y mecanismos de integración de herramientas. Prácticas de Desarrollo de Software
        • Uso de las facilidades de un IDE moderno: depuración, refactorización, búsqueda/indexación, asistentes de código basados en ML, etc. Prácticas de Desarrollo de Software

        Aprendizaje esperado (Learning Outcomes):
        Core:

        1. Describir los problemas importantes al seleccionar un conjunto de herramientas para el desarrollo de un sistema de software específico, incluyendo herramientas para seguimiento de requisitos, modelado de diseño, implementación, automatización de construcción y pruebas [Describir]
        2. Demostrar la capacidad de usar herramientas de software para apoyar el desarrollo de un producto de software de tamaño mediano [Demostrar]

        2.13.5. SE/Ingeniería de Requisitos  (KA Core: 2 hrs) ↑ Volver arriba

        Temas:
        Core

        Aprendizaje esperado (Learning Outcomes):
        Core:

        1. Comparar diferentes métodos de obtención de requisitos a lo largo de múltiples ejes [Comparar]
        2. Identificar diferencias entre dos métodos de describir requisitos funcionales (por ejemplo, entrevistas con clientes, estudios de usuarios) y las situaciones donde se preferiría cada uno [Analizar]
        3. Identificar qué comportamientos son requeridos, permitidos o prohibidos a partir de un conjunto dado de requisitos y una lista de comportamientos candidatos [Analizar]
        4. Recopilar un conjunto de requisitos para un sistema de software simple [Analizar]
        5. Identificar áreas de un sistema de software que deben cambiarse, dada una descripción del sistema y un conjunto de nuevos requisitos a implementar [Analizar]
        6. Identificar los requisitos funcionales y no funcionales en un conjunto de requisitos [Analizar]

        2.13.6. SE/Evolución y Estimación de Requisitos  (KA Core: 1 hr) ↑ Volver arriba

        Temas:
        Non Core

        • Prototipado de una herramienta tanto para obtener como para validar/confirmar requisitos.
        • Evolución del producto: cuando cambian los requisitos, cómo entender qué efecto tiene eso y qué cambios deben realizarse.
        • Estimación de esfuerzo:
          1. Aprender técnicas para estimar mejor el esfuerzo requerido para completar una tarea;
          2. Practicar la estimación y compararla con cuánto tiempo toman las tareas;
          3. La estimación de esfuerzo es bastante difícil, por lo que es probable que los estudiantes se equivoquen en muchos casos, pero ver el proceso desarrollarse con su propio trabajo es valioso. enumerate

          Aprendizaje esperado (Learning Outcomes):
          NonCore:

          1. Crear un prototipo de un sistema de software para validar un conjunto de requisitos: construir una maqueta, MVP, etc [Crear]
          2. Estimar el tiempo para completar un conjunto de tareas, luego comparar las estimaciones con el tiempo real tomado [Estimar]
          3. Determinar una secuencia de implementación para un conjunto de tareas, respetando las dependencias entre ellas, con el objetivo de retirar el riesgo lo antes posible [Determinar]
          4. Escribir una especificación de requisitos para un sistema de software simple [Escribir]

          2.13.7. SE/Principios y Arquitectura de Software  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

          Temas:
          Core

          • Principios de diseño de sistemas. Confiabilidad del Sistema
            1. Niveles de abstracción (por ejemplo, diseño arquitectónico y diseño detallado)
            2. Separación de preocupaciones (separation of concerns)
            3. Ocultación de información (information hiding)
            4. Acoplamiento y cohesión (coupling and cohesion) enumerate
            5. Arquitectura de software. Confiabilidad del Sistema
              1. Paradigmas de diseño
                1. Descomposición funcional de arriba hacia abajo/diseño por capas
                2. Arquitectura orientada a datos
                3. Análisis y diseño orientado a objetos
                4. Diseño dirigido por eventos enumerate
                5. Arquitecturas estándar (por ejemplo, cliente-servidor y arquitecturas de microservicios incluyendo discusiones sobre REST, n-capas, tuberías y filtros, Modelo Vista Controlador)
                6. Identificar límites y dependencias de componentes enumerate
                7. Programación a gran escala vs programación a pequeña escala (programming in the large vs programming in the small). Confiabilidad del Sistema
                8. Malos olores del código (code smells) y otras indicaciones de la calidad del código, distintas de la corrección. Diseño e Ingeniería de Controles de Seguridad , Análisis de Amenazas e Ingeniería de Seguridad , Computación Confiable e Ingeniería de Privacidad

                Aprendizaje esperado (Learning Outcomes):
                Core:

                1. Identificar la arquitectura de software estándar de un diseño de alto nivel dado [Analizar]
                2. Seleccionar y usar un paradigma de diseño apropiado para diseñar un sistema de software simple y explicar cómo se han aplicado los principios de diseño de sistemas en este diseño [Evaluar]
                3. Adaptar un diseño de sistema defectuoso para que siga mejor principios como la separación de preocupaciones o la ocultación de información [Crear]
                4. Identificar las dependencias entre un conjunto de componentes de software en un diseño arquitectónico [Analizar]

                2.13.8. SE/Diseño de API y Modelado  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                Temas:
                Core

                • Principios de diseño de API
                  1. Consistencia
                    1. Las API consistentes son más fáciles de aprender y menos propensas a errores
                    2. La consistencia es tanto interna (entre diferentes partes de la API) como externa (siguiendo patrones comunes de API) enumerate
                    3. Capacidad de composición (composability)
                    4. Documentación de contratos
                      1. Las operaciones de la API deben describir su efecto en el sistema, pero generalmente no su implementación
                      2. Precondiciones, postcondiciones e invariantes enumerate
                      3. Capacidad de expansión (expandability)
                      4. Reporte de errores
                        1. Los errores deben ser claros, predecibles y accionables
                        2. La entrada que no coincida con el contrato debe producir un error
                        3. Los errores que pueden gestionarse de manera confiable sin reportarse deben gestionarse enumerate enumerate
                        4. Identificar y codificar invariantes de datos e invariantes temporales
                        5. Modelos estructurales y de comportamiento de diseños de software

                        Aprendizaje esperado (Learning Outcomes):
                        Core:

                        1. Diseñar una API para un solo componente de un sistema de software grande, incluyendo la identificación y documentación de las invariantes, el contrato y las condiciones de error de cada operación [Diseñar]
                        2. Evaluar una descripción de API en términos de consistencia, capacidad de composición y capacidad de expansión [Evaluar]
                        3. Expandir un diseño existente para incluir una nueva funcionalidad [Crear]

                        2.13.9. SE/Calidad y Evaluación del Diseño  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

                        Temas:
                        Core

                        • Diseño de datos Modelado de Datos
                          1. Estructuras de datos
                          2. Sistemas de almacenamiento enumerate
                          3. Trazabilidad de requisitos
                            1. Comprender qué requisitos son satisfechos por un diseño enumerate

                            Non Core

                            Aprendizaje esperado (Learning Outcomes):
                            Core:

                            1. Diseñar un conjunto de estructuras de datos para implementar una superficie de API proporcionada [Diseñar]
                            2. Identificar qué requisitos son satisfechos por un diseño de software proporcionado [Analizar]

                            NonCore:

                            1. Traducir un diseño de software en lenguaje natural a diagramas de clases [Traducir]
                            2. Adaptar un diseño de sistema defectuoso para que siga mejor los principios de privilegio mínimo y valores predeterminados seguros ante fallos [Crear]
                            3. Contrastar dos diseños de software a través de diferentes cualidades, como eficiencia o usabilidad [Contrastar]

                            2.13.10. SE/Prácticas de Codificación  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

                            Temas:
                            Core

                            • Pruebas prácticas a pequeña escala Prácticas de Desarrollo de Software
                              1. Pruebas unitarias
                              2. Desarrollo guiado por pruebas (Test-driven development): esto es particularmente valioso para los estudiantes psicológicamente, ya que es mucho más fácil involucrarse constructivamente con el desafío de identificar entradas desafiantes para una API dada (casos límite, casos extremos) a priori. Si implementan primero, el instinto es a menudo evitar intentar hacer fallar su nueva creación, mientras que un enfoque de pruebas primero les da la satisfacción intelectual de detectar los casos problemáticos y luego ver cómo pasan más pruebas durante el proceso de desarrollo. enumerate
                              3. Documentación Prácticas de Desarrollo de Software
                                1. Documentación de la interfaz: describir los requisitos de la interfaz, potencialmente incluyendo contratos (formales o informales), pre y post condiciones, invariantes.
                                2. La documentación de la implementación debe centrarse en partes de código complicadas y no obvias, ya sea porque el código usa características avanzadas del lenguaje o porque el comportamiento del código es complejo. (No agregar comentarios que reafirmen operaciones comunes/obvias y características simples del lenguaje.)
                                  1. Aclarar el flujo de datos, cómputo, etc., centrándose en lo que el código es.
                                  2. Identificar partes sutiles/complicadas del código y refactorizar para que sean autoexplicativas si es posible o proporcionar comentarios apropiados para aclarar. enumerate enumerate
                                  3. Estilo de codificación Prácticas de Desarrollo de Software
                                    1. Guías de estilo
                                    2. Comentarios
                                    3. Nomenclatura (naming) enumerate
                                    4. "Mejores Prácticas" para la codificación: técnicas, patrones/idiomas, mecanismos para construir programas de calidad Prácticas de Desarrollo de Software , Flujo de Información y No Interferencia , Inyección y Validación de Entrada , Seguridad de Memoria y Tipos , Análisis de Malware y Seguridad Avanzada
                                      1. Prácticas de codificación defensiva
                                      2. Prácticas y principios de codificación segura
                                      3. Usar mecanismos de manejo de excepciones para hacer los programas más robustos, tolerantes a fallos enumerate
                                      4. Depuración (debugging) Prácticas de Desarrollo de Software
                                      5. Registro (logging)
                                      6. Uso de bibliotecas y frameworks desarrollados por otros Prácticas de Desarrollo de Software

                                      Aprendizaje esperado (Learning Outcomes):
                                      Core:

                                      1. Escribir pruebas unitarias apropiadas para un componente pequeño (varias funciones, un solo tipo, etc.) [Escribir]
                                      2. Escribir comentarios apropiados de interfaz y (si es necesario) de implementación para un componente pequeño [Escribir]
                                      3. Describir técnicas, patrones de codificación y mecanismos para implementar diseños para lograr propiedades deseadas como confiabilidad, eficiencia y robustez [Describir]
                                      4. Escribir código robusto utilizando mecanismos de manejo de excepciones [Escribir]
                                      5. Describir prácticas de codificación segura y defensiva [Describir]
                                      6. Seleccionar y usar un estándar de codificación definido en un proyecto de software pequeño [Usar]
                                      7. Comparar y contrastar estrategias de integración, incluyendo integración de arriba hacia abajo (top-down), de abajo hacia arriba (bottom-up) y sándwich [Comparar]
                                      8. Describir el proceso de analizar e implementar cambios en la base de código desarrollada para un proyecto específico [Describir]
                                      9. Describir el proceso de analizar e implementar cambios en una base de código existente grande [Describir]

                                      2.13.11. SE/Construcción a Escala y Proceso  (CS Core: 1 hr, KA Core: 2 hrs) ↑ Volver arriba

                                      Temas:
                                      Non Core

                                      • Pruebas a mayor escala
                                        1. Dobles de prueba (test doubles) (stubs, mocks, fakes)
                                        2. Inyección de dependencias (dependency injection) enumerate
                                        3. Secuenciación del trabajo, incluyendo identificación de dependencias, hitos y retiro de riesgo
                                          1. Identificación de dependencias: identificar las dependencias entre diferentes tareas
                                          2. Hitos: una colección de tareas que sirve como marcador de progreso cuando se completa. Idealmente, el hito abarca una unidad útil de funcionalidad.
                                          3. Retiro de riesgo: identificar qué elementos de un proyecto son riesgosos y priorizar la finalización de tareas que aborden esos riesgos. enumerate
                                          4. Problemas potenciales de seguridad en programas Flujo de Información y No Interferencia , Inyección y Validación de Entrada , Seguridad de Memoria y Tipos , Análisis de Malware y Seguridad Avanzada
                                            1. Desbordamientos de búfer y otros tipos de desbordamientos
                                            2. Condiciones de carrera (race conditions)
                                            3. Inicialización incorrecta, incluida la elección de privilegios
                                            4. Validación de entrada (input validation) enumerate
                                            5. Documentación (autogenerada)
                                            6. Contexto de desarrollo: "campo verde" (green field) vs base de código existente
                                              1. Análisis de impacto del cambio (change impact analysis)
                                              2. Realización del cambio (change actualization) enumerate
                                              3. Gestión de lanzamientos (release management)
                                              4. Prácticas de DevOps

                                              Aprendizaje esperado (Learning Outcomes):
                                              NonCore:

                                              1. Reescribir un programa simple para eliminar vulnerabilidades comunes, como desbordamientos de búfer, desbordamientos de enteros y condiciones de carrera [Aplicar]
                                              2. Escribir un componente de software que realice alguna tarea no trivial y sea resistente a errores de entrada y de tiempo de ejecución [Escribir]

                                              2.13.12. SE/Conceptos de verificación y validación  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                                              Temas:
                                              Core

                                              • Conceptos de verificación y validación
                                                1. Verificación: ?`Estamos construyendo la cosa correctamente?
                                                2. Validación: ?`Construimos la cosa correcta? enumerate
                                                3. Por qué importan las pruebas: ¿El componente sigue siendo funcional a medida que el código evoluciona?
                                                4. Objetivos de las pruebas
                                                  1. Usabilidad
                                                  2. Confiabilidad
                                                  3. Conformidad con la especificación
                                                  4. Rendimiento
                                                  5. Seguridad enumerate

                                                  Aprendizaje esperado (Learning Outcomes):
                                                  Core:

                                                  1. Explicar por qué las pruebas son importantes [Explicar]
                                                  2. Distinguir entre validación y verificación de programas [Distinguir]
                                                  3. Describir diferentes objetivos de las pruebas [Describir]

                                                  2.13.13. SE/Planificación y Tipos de Pruebas  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                                                  Temas:
                                                  Core

                                                  • Tipos de pruebas
                                                    1. Unitarias
                                                    2. Integración
                                                    3. Validación
                                                    4. Sistema enumerate
                                                    5. Diferencias estilísticas entre el código de prueba y el código de producción: DAMP vs DRY - se justifica más duplicación en el código de prueba.
                                                    6. Planificación y generación de pruebas
                                                      1. Generación de casos de prueba, a partir de modelos formales, especificaciones, etc.
                                                      2. Cobertura de pruebas
                                                        1. Matrices de prueba
                                                        2. Cobertura de código - ¿cuánto del código está probado?
                                                        3. Cobertura de entorno - ¿cuántas arquitecturas de hardware, sistemas operativos, navegadores, etc. están probados? enumerate
                                                        4. Datos y entradas de prueba enumerate

                                                        Aprendizaje esperado (Learning Outcomes):
                                                        Core:

                                                        1. Comparar y contrastar los diferentes tipos y niveles de pruebas (regresión, unitarias, integración, sistemas y aceptación) [Comparar]
                                                        2. Describir técnicas para crear un plan de pruebas y generar casos de prueba [Describir]
                                                        3. Crear un plan de pruebas para un segmento de código de tamaño mediano que incluya una matriz de pruebas y generación de datos y entradas de prueba [Crear]
                                                        4. Implementar un plan de pruebas para un segmento de código de tamaño mediano [Implementar]

                                                        2.13.14. SE/Prácticas Avanzadas de Pruebas  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                                                        Temas:
                                                        Core

                                                        • Desarrollo de pruebas
                                                          1. Desarrollo guiado por pruebas
                                                          2. Pruebas orientadas a objetos, uso de mocks e inyección de dependencias
                                                          3. Técnicas de prueba de caja opaca (anteriormente, caja negra) y caja transparente (anteriormente, caja blanca)
                                                          4. Herramientas de prueba, incluyendo cobertura de código, análisis estático y fuzzing enumerate
                                                          5. Verificación y validación en el ciclo de desarrollo
                                                            1. Revisiones de código
                                                            2. Automatización de pruebas, incluyendo automatización de herramientas
                                                            3. Pruebas pre-commit y post-commit
                                                            4. Compensaciones entre cobertura de pruebas y rendimiento/latencia de las pruebas
                                                            5. Seguimiento y priorización de defectos: reproducibilidad de los defectos reportados enumerate
                                                            6. Desafíos de verificación y validación específicos del dominio
                                                              1. Pruebas de rendimiento y evaluación comparativa (benchmarking)
                                                              2. Asincronía, paralelismo y concurrencia
                                                              3. Crítico para la seguridad (safety-critical)
                                                              4. Numérico enumerate

                                                              Aprendizaje esperado (Learning Outcomes):
                                                              Core:

                                                              1. Identificar los principios fundamentales de los métodos de desarrollo guiado por pruebas y explicar el papel de las pruebas automatizadas en estos métodos [Analizar]
                                                              2. Discutir problemas relacionados con las pruebas de software orientado a objetos [Debatir]
                                                              3. Describir el uso de mocks y la inyección de dependencias y su aplicación [Describir]
                                                              4. Realizar, como parte de una actividad en equipo, una revisión de código de un segmento de código de tamaño mediano [Evaluar]
                                                              5. Describir el papel que las herramientas pueden desempeñar en la validación del software [Describir]
                                                              6. Automatizar las pruebas en un proyecto de software pequeño [Diseñar]
                                                              7. Explicar los roles, pros y contras de las pruebas pre-commit y post-commit [Explicar]
                                                              8. Discutir las compensaciones entre la cobertura de pruebas y el rendimiento/latencia de las pruebas y cómo esto puede afectar la verificación [Debatir]
                                                              9. Usar una herramienta de seguimiento de defectos para gestionar defectos de software en un proyecto de software pequeño [Usar]
                                                              10. Discutir las limitaciones de las pruebas en ciertos dominios [Debatir]

                                                              2.13.15. SE/Herramientas y Análisis de Pruebas  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                                                              Temas:
                                                              Non Core

                                                              • Herramientas y automatización de verificación y validación
                                                                1. Análisis estático
                                                                2. Cobertura de código
                                                                3. Fuzzing
                                                                4. Análisis dinámico y contención de fallos (sanitizadores, etc.)
                                                                5. Registro y seguimiento de fallos enumerate
                                                                6. Planificación y generación de pruebas
                                                                  1. Estimación de fallos y terminación de pruebas, incluyendo siembra de defectos
                                                                  2. Uso de números aleatorios y pseudoaleatorios en las pruebas enumerate
                                                                  3. Pruebas de sistemas asíncronos, paralelos y concurrentes
                                                                  4. Verificación y validación de artefactos que no son código (documentación, materiales de capacitación)

                                                                  Aprendizaje esperado (Learning Outcomes):
                                                                  NonCore:

                                                                  1. Describir y comparar diferentes herramientas para verificación y validación [Describir]
                                                                  2. Automatizar el uso de diferentes herramientas en un proyecto de software pequeño [Diseñar]
                                                                  3. Explicar cómo y cuándo se deben usar números aleatorios en las pruebas [Explicar]
                                                                  4. Describir enfoques para la estimación de fallos [Describir]
                                                                  5. Estimar el número de fallos en una aplicación de software pequeña basándose en la densidad de fallos y la siembra de fallos [Estimar]
                                                                  6. Describir técnicas y problemas con las pruebas de software asíncrono, concurrente y paralelo [Describir]
                                                                  7. Crear un plan de pruebas para un segmento de código de tamaño mediano que contenga código asíncrono, concurrente y/o paralelo, incluyendo una matriz de pruebas y generación de datos y entradas de prueba [Crear]
                                                                  8. Describir técnicas para la verificación y validación de artefactos que no son código [Describir]

                                                                  2.13.16. SE/Pruebas de Rendimiento y Evaluación Comparativa  (CS Core: 1 hr, KA Core: 1 hr) ↑ Volver arriba

                                                                  Temas:
                                                                  Non Core

                                                                  • Pruebas de rendimiento y evaluación comparativa
                                                                    1. Rendimiento (throughput) y latencia
                                                                    2. Degradación bajo carga (pruebas de estrés, manejo FIFO vs LIFO de solicitudes)
                                                                    3. Aceleración (speedup) y escalado (scaling)
                                                                      1. Ley de Amdahl
                                                                      2. Ley de Gustafson
                                                                      3. Escalado suave (soft) y débil (weak) enumerate
                                                                      4. Identificar y medir figuras de mérito (figures of merit)
                                                                      5. Cuellos de botella de rendimiento comunes
                                                                        1. Limitado por cómputo (compute-bound)
                                                                        2. Limitado por ancho de banda de memoria
                                                                        3. Limitado por latencia enumerate
                                                                        4. Métodos estadísticos y mejores prácticas para la evaluación comparativa (benchmarking)
                                                                          1. Estimación de la incertidumbre
                                                                          2. Intervalos de confianza enumerate
                                                                          3. Análisis y presentación (gráficos, etc.)
                                                                          4. Técnicas de medición de tiempo (timing) enumerate

                                                                          Aprendizaje esperado (Learning Outcomes):
                                                                          NonCore:

                                                                          1. Describir el rendimiento (throughput) y la latencia y proporcionar ejemplos de cada uno [Describir]
                                                                          2. Explicar la aceleración (speedup) y las diferentes formas de escalado (scaling) y cómo se calculan [Explicar]
                                                                          3. Describir cuellos de botella de rendimiento comunes [Describir]
                                                                          4. Describir métodos estadísticos y mejores prácticas para la evaluación comparativa (benchmarking) de software [Describir]
                                                                          5. Explicar técnicas y desafíos para medir el tiempo al construir una evaluación comparativa (benchmark) [Explicar]
                                                                          6. Identificar las figuras de mérito, construir y ejecutar una evaluación comparativa (benchmark) y analizar estadísticamente y visualizar los resultados para un proyecto de software pequeño [Analizar]

                                                                          2.13.17. SE/Compatibilidad y Versionado de API  (KA Core: 2 hrs) ↑ Volver arriba

                                                                          Temas:
                                                                          Core

                                                                          • Ley de Hyrum / Ley de las Interfaces Implícitas
                                                                          • Compatibilidad con versiones anteriores
                                                                            1. La compatibilidad no es una propiedad de una sola entidad, es una propiedad de una relación.
                                                                            2. La compatibilidad con versiones anteriores debe evaluarse en términos de proveedor + consumidor(es) o con un modelo bien especificado de qué formas de compatibilidad aspira/promete un proveedor. enumerate
                                                                            3. Control de versiones (versioning)
                                                                              1. Versionado Semántico (SemVer)
                                                                              2. Desarrollo basado en tronco (trunk-based development) enumerate

                                                                              Aprendizaje esperado (Learning Outcomes):
                                                                              Core:

                                                                              1. Identificar tanto el comportamiento explícito como el implícito de una interfaz e identificar riesgos potenciales de la Ley de Hyrum [Analizar]
                                                                              2. Identificar cambios que pueden considerarse ampliamente "compatibles con versiones anteriores", potencialmente con declaraciones explícitas sobre qué uso está o no soportado [Analizar]
                                                                              3. Evaluar si un cambio propuesto es lo suficientemente seguro dada la metodología de control de versiones en uso para un proyecto dado [Evaluar]

                                                                              2.13.18. SE/Técnicas de Refactorización  (KA Core: 1 hr) ↑ Volver arriba

                                                                              Temas:
                                                                              Core

                                                                              • Refactorización
                                                                                1. Patrones de refactorización estándar (renombrar, integrar, extraer, etc.)
                                                                                2. Uso de herramientas de refactorización en el IDE
                                                                                3. Aplicación de herramientas de análisis estático (para identificar código que necesita refactorización, generar cambios, etc.)
                                                                                4. Valor de la refactorización como remedio para la deuda técnica enumerate

                                                                                Non Core

                                                                                • Refactorización "a Gran Escala": técnicas cuando un cambio de refactorización es demasiado grande para comprometerlo de forma segura (proyectos grandes), o cuando es imposible sincronizar el cambio entre proveedor + todos los consumidores (múltiples repositorios, consumidores con código privado).
                                                                                  1. Expresar tanto las API antiguas como las nuevas para que puedan coexistir.
                                                                                  2. Minimizar el tamaño de los cambios de comportamiento.
                                                                                  3. ?`Por qué se requieren estas técnicas?. Por ejemplo, "consumidores de API que puedo ver" vs "consumidores que no puedo ver"). enumerate

                                                                                  Aprendizaje esperado (Learning Outcomes):
                                                                                  Core:

                                                                                  1. Considerar las entradas de herramientas de análisis estático y/o los principios de Diseño de Software para identificar código que necesita refactorización [Analizar]
                                                                                  2. Refactorizar la implementación de una interfaz para mejorar el diseño, claridad, etc., con impacto mínimo/cero en los usuarios existentes [Crear]

                                                                                  NonCore:

                                                                                  1. Planificar una refactorización compleja de múltiples pasos para cambiar el comportamiento predeterminado de una API de manera segura [Planear]

                                                                                  2.13.19. SE/Conceptos de Confiabilidad  (KA Core: 2 hrs) ↑ Volver arriba

                                                                                  Temas:
                                                                                  Core

                                                                                  • Concepto de confiabilidad como probabilidad de fallo o tiempo medio entre fallos, y fallas (faults) como causa de fallos (failures)
                                                                                  • Identificar requisitos de confiabilidad para diferentes tipos de software
                                                                                  • Fallos de software causados por defectos/errores (bugs), por lo que para alta confiabilidad el objetivo es tener un mínimo de defectos - inyectando menos defectos (mejor capacitación, educación, planificación) y eliminando la mayoría de los defectos inyectados (pruebas, revisión de código, etc.)
                                                                                  • Confiabilidad del software, confiabilidad del sistema y comportamiento de fallos
                                                                                  • Ciclo de inyección y eliminación de defectos, y diferentes enfoques para la eliminación de defectos
                                                                                  • Comparar el enfoque de "presupuesto de error" (error budget) para la confiabilidad con el enfoque "libre de errores" (error-free) e identificar dominios donde cada uno es relevante.

                                                                                  Aprendizaje esperado (Learning Outcomes):
                                                                                  Core:

                                                                                  1. Describir cómo determinar el nivel de confiabilidad requerido por un sistema de software [Describir]
                                                                                  2. Explicar los problemas que existen para lograr niveles muy altos de confiabilidad [Explicar]
                                                                                  3. Comprender enfoques para minimizar fallas que pueden aplicarse en cada etapa del ciclo de vida del software [Explicar]

                                                                                  2.13.20. SE/Ingeniería de Confiabilidad  (KA Core: 1 hr) ↑ Volver arriba

                                                                                  Temas:
                                                                                  Non Core

                                                                                  • Modelos de confiabilidad de software
                                                                                  • Técnicas y modelos de tolerancia a fallos de software
                                                                                    1. Diferencias contextuales en la tolerancia a fallos (por ejemplo, hacer fallar un sistema crítico para la aviación se evita firmemente, hacer fallar un sistema de procesamiento de datos antes de que se escriban datos corruptos en el almacenamiento es muy valioso) enumerate
                                                                                    2. Prácticas de ingeniería de confiabilidad de software - incluyendo revisiones, pruebas, verificación de modelos práctica (practical model checking)
                                                                                    3. Identificación de dominios de fallos dependientes e independientes, y su impacto en la confiabilidad del sistema
                                                                                    4. Análisis basado en mediciones de la confiabilidad del software - telemetría, monitorización y alertas, paneles de control, métricas de calificación de lanzamientos, etc.

                                                                                    Aprendizaje esperado (Learning Outcomes):
                                                                                    NonCore:

                                                                                    1. Demostrar la capacidad de aplicar múltiples métodos para desarrollar estimaciones de confiabilidad para un sistema de software [Demostrar]
                                                                                    2. Identificar métodos que conducirán a la realización de una arquitectura de software que logre un nivel especificado de confiabilidad [Analizar]
                                                                                    3. Identificar formas de aplicar redundancia para lograr tolerancia a fallos [Analizar]
                                                                                    4. Identificar dependencias de punto único de fallo (single-point-of-failure, SPF) en un diseño de sistema [Analizar]

                                                                                    2.13.21. SE/Métodos Formales ↑ Volver arriba

                                                                                    Temas:
                                                                                    Non Core

                                                                                    • Especificación formal de interfaces
                                                                                      1. Especificación de pre y post condiciones
                                                                                      2. Lenguajes formales para escribir y analizar pre y post condiciones. enumerate
                                                                                      3. áreas de problemas bien atendidas por los métodos formales
                                                                                        1. Programación libre de bloqueos (lock-free), condiciones de carrera de datos
                                                                                        2. Sistemas asíncronos y distribuidos, bloqueos (deadlock), bloqueos vivos (livelock), etc. enumerate
                                                                                        3. Comparación con otras herramientas y técnicas para la detección de defectos
                                                                                          1. Pruebas
                                                                                          2. Fuzzing enumerate
                                                                                          3. Enfoques formales para el modelado y análisis de software
                                                                                            1. Verificadores de modelos (model checkers)
                                                                                            2. Buscadores de modelos (model finders) enumerate

                                                                                            Aprendizaje esperado (Learning Outcomes):
                                                                                            NonCore:

                                                                                            1. Describir el papel que las técnicas de especificación y análisis formal pueden desempeñar en el desarrollo de software complejo y comparar su uso como técnicas de validación y verificación con las pruebas [Describir]
                                                                                            2. Aplicar técnicas de especificación y análisis formal a diseños y programas de software de baja complejidad [Aplicar]
                                                                                            3. Explicar los beneficios y desventajas potenciales del uso de lenguajes de especificación formal [Explicar]

                                                                                            ¿Encontraste una errata, un curso desactualizado, un enlace roto, o tienes una sugerencia? Cuéntanos.

                                                                                            Escanea para abrir en tu teléfono