## Bloque 3 Tema 9. Repositorios: estructura y actualización. Generación de código y documentación. Metodologías de desarrollo. Pruebas. Programas para control de versiones. Plataformas de desarrollo colaborativo de software.

Este tema estudia las herramientas y metodologías que estructuran el ciclo de vida completo del desarrollo de software, desde el control de versiones hasta la entrega en producción.

---

## Apartado 1. Esquema introductorio

Al inicio del documento encontraréis el esquema introductorio, que resume en pocas líneas todos los conceptos del tema.

El esquema agrupa los contenidos en cinco bloques.

El primero trata el control de versiones, que es el sistema que registra los cambios en el código a lo largo del tiempo.

El segundo enumera los tipos de repositorios: locales, centralizados como SVN, y distribuidos como Git.

El tercero recoge las metodologías de desarrollo: las tradicionales, como cascada, modelo en V, espiral y RUP; y las ágiles, como Scrum, Kanban y XP.

El cuarto bloque resume las pruebas de software: unitarias, de integración, de sistema y de aceptación; las técnicas de caja blanca, caja negra y caja gris; la pirámide de pruebas; y los enfoques TDD y BDD.

El quinto bloque indica las plataformas colaborativas: GitHub, propiedad de Microsoft desde 2018; GitLab, que se puede instalar de forma privada en servidores propios; y Bitbucket, de la empresa Atlassian.

El esquema también menciona tres conceptos transversales que aparecerán a lo largo de todo el tema: CI/CD para la integración y entrega continua, SemVer para el versionado semántico, y el archivo punto gitignore con los mecanismos de protección de ramas y Pull Requests.

---

## Apartado 2. Repositorios: concepto y estructura

### Apartado 2.1. Qué es un repositorio

Un repositorio, también llamado repo, es un almacén centralizado o distribuido donde se guarda el código fuente de un proyecto junto con el historial completo de todos los cambios realizados sobre él.

Un repositorio no es simplemente una carpeta de archivos. Actúa como una base de datos de cambios que permite saber quién modificó qué, cuándo y por qué. Esto hace posible colaborar en equipo, revertir errores y gestionar versiones paralelas del mismo proyecto.

Los elementos que contiene un repositorio son los siguientes. El árbol de trabajo, que son los archivos actuales del proyecto. El historial de commits, que son las instantáneas del proyecto a lo largo del tiempo. Las ramas, que son líneas de desarrollo paralelas e independientes. Las etiquetas, que son marcas inmutables en commits concretos para señalar versiones de release. Y los metadatos del sistema de control de versiones.

---

### Apartado 2.2. Tipos de repositorios

Hay tres tipos de repositorios.

El primero es el repositorio local. Existe únicamente en el equipo del desarrollador, sin historial compartido ni colaboración posible. Solo es adecuado para proyectos personales sin colaboradores.

El segundo es el repositorio centralizado, que corresponde a los sistemas de control de versiones centralizados. En este modelo un único servidor central almacena todo el historial. Los desarrolladores hacen checkout del servidor para obtener los archivos, pero solo guardan localmente los ficheros del proyecto, no el historial. Los ejemplos más conocidos son SVN, que son las siglas de Subversion, y CVS, que son las siglas de Concurrent Versions System. La desventaja principal de este modelo es que representa un punto único de fallo: si el servidor no está disponible, nadie puede consultar el historial ni confirmar cambios.

El tercer tipo es el repositorio distribuido, que corresponde a los sistemas DVCS, siglas de Distributed Version Control System. En este modelo cada desarrollador tiene una copia completa del repositorio, incluyendo todo el historial. Se puede trabajar sin conexión al servidor remoto. Los ejemplos más conocidos son Git y Mercurial. Las ventajas son la ausencia de punto único de fallo, la velocidad de las operaciones locales y la gran flexibilidad en los flujos de trabajo.

---

### Apartado 2.3. Estructura de un repositorio Git

En el documento veréis el árbol de directorios que muestra la estructura de un repositorio Git. El elemento central es el directorio oculto punto git, que es el núcleo del repositorio y contiene toda la información del sistema de control de versiones.

Dentro de ese directorio hay varios elementos importantes. El archivo HEAD contiene la referencia a la rama activa actualmente. El archivo config guarda la configuración local del repositorio. La carpeta hooks contiene scripts que se ejecutan automáticamente en determinados eventos como el pre-commit o el post-merge. La carpeta objects es el almacén de todos los objetos del repositorio: blobs, trees, commits y tags. Dentro de objects existe una subcarpeta pack con los objetos empaquetados para mayor eficiencia. La carpeta refs contiene las referencias: dentro de heads están las ramas locales, dentro de remotes están las ramas remotas como origin barra main, y dentro de tags están las etiquetas. El archivo index es el área de staging.

Fuera del directorio punto git, en la raíz del proyecto, también es fundamental el archivo punto gitignore.

El archivo punto gitignore define los patrones de archivos y directorios que Git debe ignorar y no incluir en el control de versiones. En el bloque de código del documento podéis ver ejemplos habituales: la carpeta node_modules y las carpetas target y build con los compilados, los archivos de configuración local como punto env y application guion local punto properties, los ficheros compilados como los punto class, los jar y los war, y las carpetas de los IDEs como punto idea y punto vscode.

---

### Apartado 2.4. Objetos internos de Git

Git es un sistema de almacenamiento de contenido direccionable. Esto significa que cada objeto se identifica de forma única mediante el hash SHA-1 de su contenido, que son cuarenta caracteres hexadecimales. Si el contenido cambia, el hash cambia, lo que garantiza la integridad del historial.

La tabla que aparece en este apartado describe los cuatro tipos de objetos. El blob almacena el contenido bruto de un archivo, sin nombre ni ruta, solo el contenido. El tree representa un directorio y contiene una lista de blobs y otros trees con sus nombres y permisos de acceso. El commit es una instantánea del proyecto en un momento concreto, e incluye el autor, la fecha, el mensaje y la referencia al commit o commits padre. El tag es una referencia con nombre a un commit concreto, y en su versión anotada también incluye autor, fecha y mensaje propio.

Git modela el historial como un grafo acíclico dirigido, abreviado como DAG, de commits, donde cada commit apunta hacia atrás a su padre o padres. Esto garantiza que el historial sea inmutable e íntegro. Con el tiempo, los objetos sueltos se agrupan en packfiles comprimidos para ahorrar espacio en disco.

---

## Apartado 3. Control de versiones con Git

### Apartado 3.1. Áreas de trabajo en Git

Mirad el esquema de las cuatro áreas de trabajo que aparece en el documento. Git divide el trabajo en cuatro zonas bien diferenciadas que forman un flujo secuencial.

La primera zona es el directorio de trabajo, que son los archivos que veis, editáis y ejecutáis en vuestra máquina.

La segunda zona es el área de staging, también llamada índice. Los archivos marcados para el próximo commit se preparan aquí mediante el comando git add.

La tercera zona es el repositorio local, que es el historial de commits almacenado dentro del directorio punto git de vuestra máquina. Los commits se crean aquí mediante el comando git commit.

La cuarta zona es el repositorio remoto, que es la copia alojada en un servidor como GitHub o GitLab. Los cambios se envían allí con git push.

El staging area es el elemento diferencial de Git frente a otros sistemas: permite seleccionar qué cambios concretos incluir en cada commit, obteniendo un historial limpio y preciso sin necesidad de incluir todo lo modificado a la vez.

La tabla del documento muestra estas cuatro áreas con su descripción resumida.

---

### Apartado 3.2. Comandos principales de Git

El bloque de código de este apartado contiene los comandos más importantes de Git, agrupados por categorías. Vamos a repasar las más importantes.

El primer grupo es la configuración inicial. Los comandos git config con la opción global permiten establecer el nombre, el correo electrónico y el editor que Git usará por defecto en todos los repositorios de la máquina.

El segundo grupo es el de inicio del repositorio. El comando git init crea un nuevo repositorio local en el directorio actual. El comando git clone seguido de una URL descarga un repositorio remoto completo, con todo su historial, en la máquina local.

El tercer grupo es el ciclo básico. Git status muestra el estado actual de los archivos. Git diff muestra los cambios en el directorio de trabajo respecto al staging. Git diff con la opción staged muestra los cambios en staging respecto al último commit. Git add añade archivos al área de staging. Git add con punto añade todos los cambios a la vez. Git add con la opción p permite añadir cambios de forma interactiva fragmento a fragmento. Git commit con la opción m crea el commit con el mensaje indicado. Git commit con la opción amend permite modificar el último commit. Git log con las opciones oneline y graph muestra el historial de forma compacta con el grafo de ramas.

El cuarto grupo es el de ramas. Git branch lista las ramas locales y con la opción a también las remotas. Git branch seguido de un nombre crea una nueva rama. Git checkout y el comando moderno git switch permiten cambiar entre ramas. Con la opción b o c respectivamente se crea la rama y se cambia a ella en un solo paso. Git merge fusiona una rama en la rama activa. Git branch con la opción d elimina una rama si ya ha sido mergeada.

El quinto grupo es el de repositorio remoto. Git remote con la opción v muestra los remotos configurados. Git remote add origin seguido de la URL vincula el repositorio remoto. Git push envía cambios al remoto. Git pull los descarga y fusiona. Git fetch los descarga sin fusionar, permitiendo revisar los cambios antes de integrarlos.

El sexto grupo es el de etiquetas. Git tag lista las etiquetas. Git tag seguido de la versión crea una etiqueta ligera. Git tag con la opción a crea una etiqueta anotada con mensaje. Git push origin con la opción tags sube todas las etiquetas al remoto.

El séptimo grupo es el de deshacer. Git revert crea un nuevo commit que deshace el commit indicado, sin modificar el historial. Git reset con soft deshace el último commit pero mantiene los cambios en staging. Git reset con mixed los pasa al directorio de trabajo. Git reset con hard los descarta completamente, por lo que es un comando destructivo que debe usarse con precaución. Git stash guarda los cambios no commiteados en una pila temporal para recuperarlos después con git stash pop.

---

### Apartado 3.3. Flujos de trabajo con Git

El primero es Gitflow, que es un workflow estructurado con ramas de larga duración, diseñado para proyectos con ciclos de release bien definidos. Usa cinco tipos de ramas: main para el código en producción, siempre estable y etiquetado; develop para la integración de features; las ramas feature barra asterisco para las nuevas funcionalidades, que se crean desde develop y se mergean a develop; las ramas release barra asterisco para la preparación de versiones; y las ramas hotfix barra asterisco para las correcciones urgentes en producción, que se crean desde main y se mergean tanto a main como a develop.

El segundo flujo es GitHub Flow o Trunk-Based Development. Es más sencillo: solo existe main como rama principal de larga duración, las ramas de feature son de corta duración, y el proceso es Pull Request, revisión de código, CI en verde, y merge a main. Es ideal para despliegue continuo porque cada merge a main puede activar automáticamente un despliegue a producción.

En cuanto a la resolución de conflictos, un conflicto ocurre cuando dos ramas modifican las mismas líneas de un archivo. En el bloque de código del documento veréis los marcadores que Git inserta para señalar el conflicto: los signos de menor con HEAD marcan el inicio del código de la rama activa, los signos de igual separan las dos versiones, y los signos de mayor con el nombre de la otra rama cierran el bloque. El desarrollador debe editar el archivo para quedarse con la versión correcta, eliminar los marcadores y confirmar un commit de resolución.

---

### Apartado 3.4. Merge versus Rebase

La tabla de este apartado compara las tres formas principales de integrar cambios entre ramas.

El merge crea un commit de merge que une las dos ramas y conserva el historial exactamente como ocurrió. Se usa para integrar ramas de larga duración o cuando se quiere preservar el historial real.

El rebase mueve o reaplica los commits sobre una nueva base, obteniendo un historial lineal. Se usa para limpiar el historial de una feature branch antes del merge.

El merge con la opción squash comprime todos los commits de la rama en uno solo al fusionar, lo que es muy útil para mantener main con un historial muy limpio.

Hay una regla de oro que nunca debe olvidarse: nunca se deben rebasear commits que ya han sido publicados en un repositorio compartido, porque el rebase reescribe el historial y puede romper el trabajo de otros desarrolladores.

---

### Apartado 3.5. Comandos avanzados de Git

El bloque de código de este apartado muestra cuatro grupos de comandos avanzados.

El primero es el rebase. El comando git rebase main reaplica los commits de la rama actual sobre la punta de main. El comando git rebase con la opción i permite un rebase interactivo que abre un editor para reorganizar, fusionar, editar o eliminar commits de los últimos N commits indicados.

El segundo es cherry-pick, que aplica un commit concreto de otra rama a la rama activa sin necesidad de fusionar ramas completas.

El tercero es bisect, que realiza una búsqueda binaria en el historial para encontrar el commit exacto que introdujo un bug. Se marca el commit actual como malo y un commit anterior conocido como bueno, y Git va haciendo checkout de commits intermedios hasta localizar el culpable.

El cuarto es blame, que muestra línea a línea quién modificó cada parte de un archivo y en qué commit.

También se menciona reflog, que es el historial local de todos los movimientos de HEAD, muy útil para recuperar commits o ramas que parecían perdidas.

---

## Apartado 4. Generación de código y documentación

### Apartado 4.1. Generación de código

La primera tabla de este apartado recoge las principales herramientas de generación de código.

El scaffolding o andamiaje genera automáticamente la estructura inicial de un proyecto. Ejemplos son Angular CLI, Spring Initializr y create-react-app.

Los generadores ORM crean el código de acceso a la base de datos a partir del modelo de datos. Ejemplos son Hibernate, Entity Framework y JPA.

Los generadores de API crean código cliente y servidor a partir de la especificación OpenAPI o Swagger.

Los compiladores y transpiladores transforman código de un lenguaje a otro. Los más comunes son TypeScript a JavaScript, SASS y LESS a CSS, y Kotlin a bytecode de la JVM.

Las plantillas o templates como Freemarker, Thymeleaf, Mustache y Jinja2 generan HTML u otros formatos a partir de datos dinámicos.

Los linters y formatters como ESLint, Prettier, Checkstyle y Black garantizan calidad y estilo homogéneo en el código de todo el equipo.

Respecto a CI/CD, hay que distinguir tres conceptos. La integración continua o CI consiste en que cada push activa automáticamente la compilación, el análisis de código y la ejecución de pruebas, detectando errores de integración en minutos. La entrega continua o Continuous Delivery implica que el artefacto resultante está siempre listo para desplegar, pero el despliegue final puede requerir aprobación manual. El despliegue continuo o Continuous Deployment va un paso más allá: cada cambio validado se despliega automáticamente en producción sin ninguna intervención humana.

Las herramientas más conocidas son Jenkins, GitHub Actions, GitLab CI/CD, Azure DevOps, Travis CI y CircleCI.

La segunda tabla y el bloque de diagrama que aparecen en el documento muestran las fases típicas de un pipeline CI/CD. El flujo va desde el commit inicial hasta el despliegue en producción, pasando por la compilación, el análisis estático, las pruebas unitarias, las pruebas de integración, el análisis de seguridad, el empaquetado del artefacto, el despliegue en staging, las pruebas de aceptación y finalmente el despliegue en producción. La tabla asociada muestra las herramientas habituales en cada fase: Maven o Gradle para la compilación, SonarQube o ESLint para el análisis estático, JUnit o Jest para las pruebas unitarias, TestContainers o Newman para las pruebas de integración, OWASP Dependency-Check o Snyk para el análisis de seguridad, Docker o JAR y WAR para el empaquetado, y Kubernetes, Ansible o Terraform para el despliegue.

---

### Apartado 4.2. Documentación del código

En el apartado de documentación del código aparecen dos bloques de código como ejemplo.

El primer ejemplo muestra la sintaxis de Javadoc en Java. Los comentarios de documentación se escriben entre barra asterisco asterisco y asterisco barra. Las etiquetas más usadas son arroba param para documentar los parámetros de entrada, arroba return para el valor de retorno, arroba throws para las excepciones que puede lanzar, arroba since para la versión desde la que existe el método, y arroba see para referencias cruzadas.

El segundo ejemplo muestra la sintaxis de docstrings en Python. La cadena de documentación se escribe entre comillas triples. Las secciones habituales son Args para los parámetros, Returns para el valor de retorno, Raises para las excepciones, y Example para mostrar un ejemplo de uso.

La tabla de herramientas de documentación recoge las principales opciones. Javadoc genera HTML desde los comentarios de Java. Sphinx y pdoc son las herramientas para Python. JSDoc cubre JavaScript y TypeScript. Doxygen soporta C, C++ y otros lenguajes. Swagger y OpenAPI generan documentación interactiva para APIs REST. ReadTheDocs permite publicar la documentación técnica de forma online. MkDocs y AsciiDoc se usan para la documentación general de proyectos.

---

### Apartado 4.3. Versionado semántico

El versionado semántico, definido en la web semver punto org, establece un formato con tres números separados por puntos: MAJOR punto MINOR punto PATCH.

La tabla de este apartado explica cuándo se incrementa cada campo. El campo MAJOR se incrementa cuando se introduce un cambio incompatible con la API anterior, lo que se llama un breaking change. El campo MINOR se incrementa cuando se añade nueva funcionalidad de forma compatible hacia atrás. El campo PATCH se incrementa cuando se corrige un error de forma compatible hacia atrás.

Los ejemplos que aparecen a continuación ilustran esto. La versión 1.0.0 es la primera versión estable. La versión 1.1.0 añade nueva funcionalidad sin romper nada. La versión 1.1.1 corrige un bug. La versión 2.0.0 representa un cambio de API incompatible con la versión 1.x. Los pre-releases se indican con un guion: 1.0.0-alpha, 1.0.0-beta.1, 1.0.0-rc.1.

El archivo CHANGELOG.md documenta qué cambia entre versiones. Su mantenimiento es una buena práctica fundamental en proyectos tanto open source como corporativos.

---

## Apartado 5. Metodologías de desarrollo de software

### Apartado 5.1. Metodologías tradicionales

Las metodologías tradicionales o predictivas siguen un plan detallado desde el principio del proyecto.

La metodología en cascada o waterfall divide el proyecto en fases secuenciales y sin solapamiento. En el documento las veréis numeradas: requisitos, análisis, diseño, implementación, pruebas, despliegue y mantenimiento. Cada fase debe completarse antes de iniciar la siguiente. Su principal ventaja es que es sencilla de gestionar y genera documentación exhaustiva. Su principal inconveniente es que es extremadamente inflexible ante cambios: los errores de análisis se descubren en la fase de pruebas, cuando son muy costosos de corregir.

El modelo en V extiende la cascada asociando simétricamente cada fase de desarrollo con su fase de pruebas correspondiente. En el diagrama del documento veréis las correspondencias: los requisitos del sistema se corresponden con las pruebas de aceptación o UAT, el diseño del sistema con las pruebas del sistema, el diseño de componentes con las pruebas de integración, y la codificación con las pruebas unitarias. La ventaja clave frente a la cascada es que las pruebas se diseñan desde el principio, no como una actividad de última hora.

El modelo en espiral de Boehm, publicado en 1986, combina la iteración con el análisis de riesgos en cada ciclo. Cada vuelta de la espiral recorre cuatro cuadrantes: planificación de objetivos y restricciones, análisis e identificación de riesgos técnicos, ingeniería del incremento del ciclo, y evaluación por parte del cliente con planificación de la siguiente espiral. Es adecuado para proyectos grandes con incertidumbre significativa.

La metodología RUP, siglas de Rational Unified Process, es iterativa, incremental y orientada a la arquitectura. Se divide en cuatro fases: Inicio, Elaboración, Construcción y Transición. Cada fase contiene varias iteraciones con entregables definidos. Usa artefactos UML como diagramas de clases, de secuencia y de casos de uso. Está orientada a proyectos empresariales grandes y complejos.

---

### Apartado 5.2. Metodologías ágiles

El Manifiesto Ágil fue publicado en 2001 por diecisiete expertos en desarrollo de software. Establece cuatro valores y doce principios.

Los cuatro valores son los siguientes. Los individuos y las interacciones por encima de los procesos y las herramientas. El software funcionando por encima de la documentación exhaustiva. La colaboración con el cliente por encima de la negociación de contratos. La respuesta al cambio por encima de seguir un plan.

Es importante recordar que el Manifiesto no dice que los elementos de la derecha no tengan valor. Lo que dice es que los elementos de la izquierda se valoran más.

---

En cuanto a Scrum, es el framework ágil más utilizado. Consultad la tabla de este apartado, que recoge todos los elementos del framework.

Los artefactos son tres. El Product Backlog es la lista priorizada de todas las funcionalidades del producto. El Sprint Backlog contiene las tareas seleccionadas para el sprint actual. El Incremento es el resultado de cada sprint: software funcional que cumple la Definition of Done.

Los eventos son cinco. La Sprint Planning es la reunión de inicio del sprint donde se seleccionan y descomponen las tareas. El Daily Scrum es la reunión diaria de quince minutos donde cada miembro responde a tres preguntas: qué hice ayer, qué haré hoy y qué impedimentos tengo. La Sprint Review es la demostración del incremento al cliente al final del sprint. La Sprint Retrospective es la reflexión del equipo sobre qué funcionó y qué mejorar en el siguiente sprint. Y el Sprint en sí mismo es una iteración de una a cuatro semanas con un entregable potencialmente funcional al final.

Los roles son tres. El Product Owner representa al cliente, gestiona el Product Backlog y decide la prioridad de los requisitos. El Scrum Master facilita el proceso, elimina los impedimentos y protege al equipo de interferencias externas. El Development Team es el equipo autogestionado y multifuncional que desarrolla el producto.

Las métricas de Scrum más importantes son las siguientes. La velocity mide los story points completados por sprint y sirve para prever la capacidad del equipo y estimar entregas futuras. El burn-down chart es una gráfica que muestra el trabajo restante en el sprint día a día, permitiendo detectar desviaciones a tiempo. La Definition of Done, abreviada DoD, son los criterios acordados que debe cumplir un incremento para considerarse terminado. La Definition of Ready, abreviada DoR, son los criterios que debe cumplir un ítem del backlog para poder entrar en un sprint.

---

Kanban es un sistema de gestión visual del trabajo basado en un tablero con columnas que representan los estados del trabajo, habitualmente Pendiente, En progreso, Revisión y Hecho.

El principio fundamental de Kanban es limitar el trabajo en curso mediante los límites WIP, que son las siglas de Work In Progress. Estos límites establecen el número máximo de tareas simultáneas por columna, reduciendo el multitasking y mejorando el flujo.

A diferencia de Scrum, Kanban no tiene sprints fijos: el trabajo fluye de forma continua.

Las métricas clave son el lead time, que mide el tiempo total desde que se solicita una tarea hasta que se entrega, y el cycle time, que mide el tiempo desde que se empieza a trabajar en una tarea hasta que se entrega.

Kanban es muy adecuado para equipos de mantenimiento, soporte y operaciones.

---

XP, que son las siglas de Extreme Programming, es una metodología ágil basada en un conjunto de prácticas técnicas intensas orientadas a la calidad del código.

Las prácticas más importantes son el TDD o Test-Driven Development, en el que los tests se escriben antes que el código; el pair programming o programación en pareja, en la que dos desarrolladores comparten pantalla y teclado; la integración continua, que implica integrar los cambios varias veces al día; el refactoring continuo para mejorar el código sin añadir funcionalidad; y el principio YAGNI, que son las siglas de You Ain't Gonna Need It, es decir, no implementar lo que no se necesita aún.

---

La tabla comparativa al final del apartado cinco resume las diferencias entre metodologías. Las columnas son cascada, modelo en V, Scrum, Kanban y XP. Las filas comparan la planificación, la respuesta a cambios, la documentación, el enfoque de pruebas y el tipo de proyecto para el que es más adecuada cada metodología.

---

## Apartado 6. Pruebas de software

### Apartado 6.1. Objetivos de las pruebas

Las pruebas del software tienen cinco objetivos fundamentales.

El primero es detectar defectos lo antes posible.

El segundo es verificar que el software está construido correctamente según el diseño, respondiendo a la pregunta ¿estamos construyendo el sistema correctamente?

El tercero es validar que el software satisface las necesidades reales del usuario, respondiendo a la pregunta ¿estamos construyendo el sistema correcto?

El cuarto es aumentar la confianza en la calidad del producto.

El quinto es proporcionar información para la toma de decisiones de release.

Es importante recordar esta distinción entre verificación y validación, que suele aparecer en preguntas de examen.

---

### Apartado 6.2. Niveles de prueba

Hay cuatro niveles de prueba.

Las pruebas unitarias comprueban el funcionamiento de la unidad mínima de código, que puede ser una función, un método o una clase, de forma completamente aislada del resto del sistema. Para aislarlas se usan mocks y stubs, que son objetos que simulan el comportamiento de las dependencias externas como bases de datos, servicios o APIs. Son las pruebas más rápidas de ejecutar y deben ser las más numerosas del proyecto, formando la base de la pirámide de pruebas. Las herramientas más conocidas son JUnit 5 y Mockito para Java, pytest para Python, y Jest para JavaScript.

Las pruebas de integración verifican que varios módulos o componentes funcionan correctamente al trabajar juntos. Detectan problemas de interfaz entre módulos, como formatos de datos incorrectos o errores de comunicación. Las herramientas habituales son TestContainers, Spring Boot Test y Postman con Newman.

Las pruebas de sistema comprueban el sistema completo integrado en un entorno similar a producción, verificando el comportamiento frente a los requisitos tanto funcionales como no funcionales, incluyendo rendimiento, seguridad y usabilidad.

Las pruebas de aceptación, conocidas en inglés como UAT o User Acceptance Testing, son realizadas por el usuario final o cliente para confirmar que el sistema cumple los requisitos del negocio y está listo para producción. Su criterio de aprobación se define en la Definition of Done. En metodologías ágiles pueden automatizarse mediante BDD.

---

### Apartado 6.3. Técnicas de prueba

Hay tres técnicas principales.

La caja negra o Black-box Testing prueba la funcionalidad sin conocer la implementación interna. Se analizan las entradas y las salidas esperadas. Las técnicas dentro de la caja negra son las particiones de equivalencia, que dividen los valores de entrada en clases equivalentes para reducir el número de casos de prueba; el análisis de valores límite, que prueba los extremos de cada partición; las tablas de decisión, que cubren todas las combinaciones de condiciones; y las pruebas basadas en estado, que verifican las transiciones entre estados del sistema.

La caja blanca o White-box Testing prueba conociendo y analizando el código fuente interno. El objetivo es cubrir el máximo de rutas de ejecución. Las métricas de cobertura son tres: la cobertura de líneas, que mide el porcentaje de líneas ejecutadas por los tests; la cobertura de ramas, que mide el porcentaje de ramas condicionales como los if y los else cubiertas; y la cobertura de caminos, que mide el porcentaje de caminos posibles de ejecución y es la más completa pero también la más costosa. Las herramientas de cobertura son JaCoCo para Java, Istanbul y nyc para JavaScript, y coverage punto py para Python.

La caja gris o Grey-box Testing combina ambos enfoques: se conoce la estructura interna pero las pruebas se diseñan desde la perspectiva del usuario.

---

### Apartado 6.4. Tipos de pruebas por objetivo

La tabla de este apartado recoge los principales tipos de pruebas clasificados por su objetivo.

Las pruebas de regresión verifican que los cambios nuevos no han roto funcionalidades existentes. Se automatizan en el pipeline de CI.

Las pruebas de rendimiento o carga verifican el comportamiento bajo alta demanda. Las herramientas habituales son JMeter, Gatling y k6.

Las pruebas de estrés verifican el comportamiento cuando el sistema supera su capacidad máxima.

Las pruebas de seguridad o Pen Testing buscan vulnerabilidades explotables. Las herramientas habituales son OWASP ZAP y Burp Suite.

Las pruebas de usabilidad verifican la facilidad de uso para el usuario final.

Las pruebas de accesibilidad verifican el cumplimiento de los estándares WCAG 2.1.

El smoke testing son pruebas rápidas para verificar que las funciones básicas del sistema arrancan y responden correctamente.

Las pruebas End-to-End o E2E simulan el flujo completo de un usuario a través del navegador. Las herramientas más usadas son Selenium, Cypress y Playwright.

Las pruebas de mutación modifican el código fuente de forma deliberada para verificar que los tests existentes detectan esos cambios. Las herramientas son PIT para Java y Stryker para JavaScript.

---

### Apartado 6.5. TDD: Test Driven Development

TDD sigue el ciclo Red, Green, Refactor.

En la fase Red se escribe un test que falla, porque la funcionalidad que prueba todavía no existe. El test debe fallar por el motivo correcto, no por un error de sintaxis.

En la fase Green se escribe el código mínimo necesario para que ese test pase. No importa que el código sea provisional o poco elegante en este momento.

En la fase Refactor se mejora el diseño y la legibilidad del código sin que fallen los tests existentes.

Las ventajas de TDD son un código más simple y desacoplado, un alto nivel de cobertura de pruebas desde el inicio, y que los propios tests actúan como documentación viva del comportamiento esperado del sistema.

---

### Apartado 6.6. BDD: Behavior Driven Development

BDD es una extensión del TDD que describe el comportamiento del sistema en lenguaje natural comprensible por el cliente, usando la sintaxis Given, When, Then, que en español sería Dado que, Cuando, Entonces.

En el bloque de código del documento veréis dos escenarios escritos en formato Gherkin. El primer escenario describe el login correcto: dado que el usuario ana existe en el sistema, cuando intenta iniciar sesión con la contraseña correcta, entonces debe acceder al panel de control y ver el mensaje de bienvenida. El segundo escenario describe el login fallido: dado el mismo usuario, cuando intenta iniciar sesión con contraseña incorrecta, entonces debe ver el mensaje de credenciales incorrectas.

Las herramientas que implementan BDD son Cucumber para Java, Ruby y JavaScript; Behave para Python; y SpecFlow para el ecosistema punto NET.

---

### Apartado 6.7. Pirámide de pruebas

El diagrama de este apartado muestra la pirámide de pruebas definida por Mike Cohn, que establece la proporción ideal de cada tipo de prueba en un proyecto.

La base de la pirámide está formada por las pruebas unitarias. Deben ser las más numerosas, se ejecutan en milisegundos y tienen un coste bajo porque no requieren infraestructura externa.

El nivel intermedio está formado por las pruebas de integración. Son más reducidas en número, requieren infraestructura como bases de datos o contenedores, y se ejecutan en segundos.

La cima de la pirámide está formada por las pruebas End-to-End o de interfaz de usuario. Deben ser pocas, se ejecutan en minutos y son las más frágiles y caras de mantener porque dependen del estado completo del sistema.

El antipatrón contrario se llama pirámide invertida o cono de helado: pocas pruebas unitarias y muchas pruebas de UI. El resultado es un conjunto de pruebas lento, frágil y muy caro de mantener. Este es el patrón que se debe evitar.

---

## Apartado 7. Plataformas de desarrollo colaborativo

### Apartado 7.1. GitHub

GitHub es la mayor plataforma mundial de alojamiento de código Git. Fue adquirida por Microsoft en 2018.

Las funcionalidades principales son las siguientes. Los Pull Requests son el mecanismo principal de colaboración: una propuesta de cambios para su revisión y discusión antes de fusionarlos con la rama principal. Los Issues permiten gestionar tareas, bugs, mejoras y discusiones del proyecto. GitHub Actions proporciona CI/CD integrado, configurado mediante ficheros YAML en la carpeta punto github barra workflows. GitHub Pages permite alojar sitios estáticos gratuitamente directamente desde el repositorio. GitHub Copilot es el asistente de código basado en inteligencia artificial. GitHub Codespaces proporciona un entorno de desarrollo completo en la nube, accesible desde el navegador. GitHub Packages es el registro integrado de artefactos para npm, Maven, Docker y otros formatos. Dependabot es el bot que detecta dependencias vulnerables y propone actualizaciones automáticas. CodeQL y Secret Scanning proporcionan análisis de seguridad integrado en el repositorio.

---

### Apartado 7.2. GitLab

GitLab está disponible como servicio en la nube en gitlab punto com y también como instalación on-premise en servidores propios, lo que significa que la organización controla completamente el código y los datos.

Su CI/CD nativo es muy completo y se configura mediante el fichero punto gitlab guion ci punto yml. El pipeline se organiza en stages como build, test y deploy, y permite definir environments para staging y producción.

Incluye un Container Registry integrado para imágenes Docker, GitLab Pages para documentación y sitios estáticos, y herramientas completas de gestión de proyectos con wikis, tableros Kanban, milestones y epics.

GitLab es muy utilizada en las Administraciones Públicas y entornos corporativos precisamente por ofrecer la opción on-premise, que permite mantener el control total del código sin depender de servicios externos.

---

### Apartado 7.3. Bitbucket

Bitbucket es la plataforma de control de versiones de Atlassian, la misma empresa que desarrolla Jira y Confluence.

Su principal característica diferencial es la integración nativa con Jira, que permite vincular commits y Pull Requests directamente a las tareas del proyecto de Jira.

Su servicio de CI/CD integrado se llama Bitbucket Pipelines y se configura mediante el fichero bitbucket guion pipelines punto yml.

Originalmente era compatible con Git y Mercurial, aunque el soporte a Mercurial se descontinuó en 2020.

Es la plataforma más habitual en entornos empresariales que utilizan el ecosistema Atlassian completo, es decir, Jira más Confluence más Bitbucket.

---

### Apartado 7.4. Otras herramientas del ciclo de vida

La tabla de este apartado recoge las herramientas complementarias más importantes del ciclo de vida del software.

Jira es la herramienta de gestión de proyectos de Atlassian, con seguimiento de tareas, sprints, backlog y tableros Kanban y Scrum.

Confluence es la wiki corporativa de Atlassian, integrada de forma nativa con Jira.

SonarQube realiza análisis estático de calidad del código, detectando code smells, midiendo la cobertura de pruebas, identificando vulnerabilidades de seguridad y señalando duplicaciones de código.

Jenkins es el servidor de automatización de CI/CD open-source más extenso, altamente extensible mediante plugins.

Docker Hub es el repositorio de imágenes Docker públicas y privadas más utilizado.

Nexus y Artifactory son repositorios de artefactos para almacenar y gestionar dependencias de Maven, npm, Docker y Helm charts, y también actúan como proxy de repositorios externos.

Azure DevOps es la suite DevOps completa de Microsoft, que integra en una sola plataforma los repos, los tableros de trabajo, los pipelines de CI/CD, el registro de artefactos y los planes de prueba.

---

### Apartado 7.5. Funcionalidades colaborativas clave

La tabla final de este apartado recoge las funcionalidades que son comunes a las principales plataformas colaborativas.

El fork es una copia independiente de un repositorio en la cuenta del desarrollador. Es la base del modelo open source, ya que permite contribuir a proyectos sin tener permiso de escritura directo en el repositorio original.

El Pull Request o Merge Request es la solicitud formal para integrar los cambios de una rama en otra, incluyendo el proceso de revisión y aprobación.

El code review o revisión de código es el proceso por el cual otro u otros desarrolladores examinan los cambios propuestos antes de que sean mergeados.

La protección de ramas impide el push directo a las ramas protegidas como main o develop, obligando a que todos los cambios pasen por un Pull Request y tengan el CI en verde.

Los webhooks son notificaciones HTTP automáticas que la plataforma envía a servicios externos cada vez que se produce un evento, como un push o un Pull Request.

La wiki es la documentación del proyecto integrada en la propia plataforma.

Los milestones agrupan issues y Pull Requests para el seguimiento de versiones concretas o fechas de entrega.

Las labels o etiquetas clasifican los issues y Pull Requests por tipo: bug, enhancement, documentation, y otros.

---

## Apartado 8. Resumen: conceptos clave para el examen

El documento finaliza con la tabla de conceptos clave para el examen. Vamos a repasar los más importantes en grupos temáticos.

Sobre control de versiones: DVCS es el sistema de control de versiones distribuido en el que cada clon tiene el historial completo. Git es el DVCS más usado, basa su almacenamiento en objetos SHA-1 y modela el historial como un grafo acíclico dirigido. Un commit es una instantánea identificada por su hash SHA-1 que apunta a su commit padre. Una branch es una línea de desarrollo paralela; main es la rama principal por convención. El merge preserva el historial real; el rebase lo lineariza, y nunca debe aplicarse a commits ya publicados. Gitflow usa las ramas main, develop, feature, release y hotfix. El archivo punto gitignore define qué ficheros excluir del control de versiones.

Sobre CI/CD y versionado: CI es la integración continua; CD es la entrega o el despliegue continuo. Las herramientas principales son Jenkins, GitHub Actions y GitLab CI. SemVer usa el formato MAJOR punto MINOR punto PATCH: MAJOR para breaking changes, MINOR para nuevas features y PATCH para correcciones de bugs.

Sobre metodologías: la cascada tiene fases secuenciales sin retroceso y los errores se detectan tarde. El modelo en V añade pruebas planificadas simétricamente desde el diseño. El Manifiesto Ágil es de 2001 y tiene cuatro valores centrados en individuos, software funcionando, colaboración y respuesta al cambio. Scrum usa sprints de una a cuatro semanas con los roles Product Owner, Scrum Master y Development Team y los eventos Planning, Daily, Review y Retrospective. La velocity mide los story points completados por sprint. La DoD son los criterios de terminado de un incremento. Kanban usa tablero visual con límites WIP y mide lead time y cycle time.

Sobre pruebas: TDD sigue el ciclo Red, Green, Refactor y el test se escribe antes que el código. BDD usa la sintaxis Given, When, Then con herramientas como Cucumber y Behave. La prueba unitaria prueba la unidad mínima de forma aislada con mocks y stubs. La prueba de integración prueba varios módulos juntos. La prueba de aceptación o UAT la realiza el usuario final. La caja negra prueba la funcionalidad sin ver el código. La caja blanca prueba conociendo el código y mide cobertura de líneas, ramas y caminos. La pirámide de pruebas tiene muchas pruebas unitarias en la base, pruebas de integración en el nivel intermedio y pocas pruebas E2E en la cima.

Sobre plataformas: GitHub es la plataforma más popular, fue adquirida por Microsoft en 2018 y usa GitHub Actions para CI/CD y GitHub Copilot para asistencia con IA. GitLab permite instalación on-premise y es muy usada en las Administraciones Públicas; su CI/CD se configura con el fichero punto gitlab guion ci punto yml. Bitbucket pertenece a Atlassian y tiene integración nativa con Jira. SonarQube realiza análisis estático de calidad del código detectando code smells, midiendo cobertura e identificando vulnerabilidades.

