35 KiB
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.
1. Esquema introductorio (visión rápida)
Control de versiones → Sistema que registra los cambios en el código a lo largo del tiempo.
Tipos de repositorios
- Locales, centralizados (SVN), distribuidos (Git)
Metodologías de desarrollo
- Tradicionales: cascada, modelo en V, espiral, RUP
- Ágiles: Scrum, Kanban, XP
Pruebas de software
- Unitarias, integración, sistema, aceptación (UAT)
- Caja blanca vs. caja negra vs. caja gris
- Pirámide de pruebas: unitarias → integración → E2E
- TDD (Red → Green → Refactor) y BDD (Given-When-Then)
Plataformas colaborativas
- GitHub (Microsoft, 2018), GitLab (on-premise), Bitbucket (Atlassian)
Conceptos transversales
- CI/CD: integración, entrega y despliegue continuos
- SemVer: MAJOR.MINOR.PATCH
- .gitignore, hooks, protección de ramas, Pull Request
2. Repositorios: concepto y estructura
2.1 Qué es un repositorio
Un repositorio (repository o repo) es un almacén centralizado o distribuido donde se guarda el código fuente y el historial completo de todos los cambios realizados sobre él.
Un repositorio no solo almacena el estado actual del código: actúa como una base de datos de cambios que permite conocer quién modificó qué, cuándo y por qué. Esto hace posible colaborar en equipo, revertir errores y gestionar versiones paralelas.
Contiene:
- El árbol de trabajo (working tree): los archivos actuales del proyecto.
- El historial de commits: cada instantánea del proyecto en el tiempo.
- Las ramas (branches): líneas de desarrollo paralelas e independientes.
- Las etiquetas (tags): marcas inmutables en commits concretos (versiones de release).
- Los metadatos del sistema de control de versiones.
2.2 Tipos de repositorios
Repositorio local
- Existe solo en el equipo del desarrollador.
- Sin historial compartido ni colaboración directa.
- Adecuado solo para proyectos personales sin colaboradores.
Repositorio centralizado (VCS centralizado)
- Un único servidor central almacena todo el historial.
- Los desarrolladores hacen checkout del servidor para obtener los archivos; solo guardan los ficheros en local, no el historial.
- Ejemplos: SVN (Subversion), CVS (Concurrent Versions System).
- Desventaja principal: punto único de fallo; si el servidor no está disponible, nadie puede consultar el historial ni confirmar cambios.
Repositorio distribuido (DVCS)
- Cada desarrollador tiene una copia completa del repositorio, incluyendo todo el historial.
- Se puede trabajar sin conexión al servidor remoto.
- Ejemplos: Git, Mercurial.
- Ventajas: sin punto único de fallo, operaciones locales muy rápidas, flujos de trabajo muy flexibles.
2.3 Estructura de un repositorio Git
El directorio .git/ es el núcleo del repositorio. La estructura completa es:
proyecto/
├── .git/ ← Directorio oculto con todos los metadatos de Git
│ ├── HEAD ← Referencia a la rama activa actualmente
│ ├── config ← Configuración local del repositorio
│ ├── hooks/ ← Scripts ejecutados en eventos (pre-commit, post-merge…)
│ ├── objects/ ← Almacén de objetos: blobs, trees, commits, tags
│ │ └── pack/ ← Objetos empaquetados (packfiles) para mayor eficiencia
│ ├── refs/
│ │ ├── heads/ ← Ramas locales
│ │ ├── remotes/ ← Ramas remotas (origin/main, origin/develop…)
│ │ └── tags/ ← Etiquetas
│ └── index ← Área de staging (índice)
├── src/
├── tests/
├── .gitignore ← Patrones de archivos excluidos del control de versiones
└── README.md
El archivo .gitignore
El archivo .gitignore define qué archivos y directorios debe ignorar Git. Es una práctica fundamental para excluir del repositorio lo que no debe versionarse:
# Dependencias externas
node_modules/
target/
build/
# Entornos y configuraciones locales
.env
*.env.local
application-local.properties
# Compilados y ejecutables
*.class
*.jar
*.war
# Carpetas de IDEs
.idea/
.vscode/
*.iml
2.4 Objetos internos de Git
Git es un sistema de almacenamiento de contenido direccionable: cada objeto se identifica de forma única por el hash SHA-1 (40 caracteres hexadecimales) calculado sobre su contenido. Si el contenido cambia, el hash cambia, lo que garantiza la integridad del historial.
| Objeto | Descripción |
|---|---|
| blob | Contenido bruto de un archivo (sin nombre ni ruta, solo contenido) |
| tree | Directorio: lista de blobs y otros trees con sus nombres y permisos de acceso |
| commit | Instantánea + autor + fecha + mensaje + referencia al commit padre (o padres en un merge) |
| tag | Referencia con nombre a un commit concreto; los tags anotados incluyen autor, fecha y mensaje propio |
Git modela el historial como un grafo acíclico dirigido (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.
3. Control de versiones con Git
3.1 Áreas de trabajo en Git
Working Directory → Staging Area (index) → Repositorio local → Repositorio remoto
(editar) (git add) (git commit) (git push)
| Área | Descripción |
|---|---|
| Working directory | Archivos que ves y editas |
| Staging area | Archivos preparados para el próximo commit |
| Repositorio local | Historial de commits almacenado en .git/ |
| Repositorio remoto | Copia alojada en un servidor (GitHub, GitLab…) |
El staging area es el elemento diferencial de Git: 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.
3.2 Comandos principales de Git
# Configuración inicial
git config --global user.name "Nombre Apellido"
git config --global user.email "email@ejemplo.com"
git config --global core.editor "code --wait" # editor por defecto
# Iniciar repositorio
git init # nuevo repo local en el directorio actual
git clone URL # clonar repo remoto (crea directorio local)
git clone URL mi-carpeta # clonar en un directorio con nombre concreto
# Ciclo básico
git status # ver estado de los archivos
git diff # cambios en working directory vs staging
git diff --staged # cambios en staging vs último commit
git add archivo.py # añadir un archivo concreto al staging
git add . # añadir todos los cambios al staging
git add -p # añadir de forma interactiva (por fragmentos)
git commit -m "mensaje" # crear commit con mensaje en línea
git commit --amend # modificar el último commit (mensaje o contenido)
git log --oneline --graph # historial compacto con grafo de ramas
# Ramas
git branch # listar ramas locales
git branch -a # listar ramas locales y remotas
git branch nueva-rama # crear rama en el commit actual
git checkout nueva-rama # cambiar a una rama existente
git checkout -b nueva-rama # crear rama y cambiar a ella (shortcut)
git switch nueva-rama # cambiar de rama (comando moderno)
git switch -c nueva-rama # crear y cambiar (comando moderno)
git merge otra-rama # fusionar otra-rama en la rama activa
git branch -d rama # eliminar rama (solo si ya está mergeada)
git branch -D rama # eliminar rama forzosamente
# Repositorio remoto
git remote -v # ver remotos configurados
git remote add origin URL # vincular repositorio remoto como 'origin'
git push origin main # subir rama main al remoto
git push -u origin main # subir y establecer upstream (tracking)
git pull origin main # descargar y fusionar cambios del remoto
git fetch origin # descargar cambios sin fusionar
# Etiquetas
git tag # listar etiquetas
git tag v1.0.0 # etiqueta ligera en el commit actual
git tag -a v1.0.0 -m "Versión estable 1.0.0" # etiqueta anotada
git push origin --tags # subir todas las etiquetas al remoto
git push origin v1.0.0 # subir una etiqueta concreta
# Deshacer y reescribir historial
git revert HASH # crear nuevo commit que deshace el commit indicado
git reset --soft HEAD~1 # deshacer último commit, mantener cambios en staging
git reset --mixed HEAD~1 # deshacer último commit, pasar cambios a working dir
git reset --hard HEAD~1 # deshacer último commit y descartar cambios (¡destructivo!)
git stash # guardar cambios no commiteados en una pila temporal
git stash list # listar todos los stashes guardados
git stash pop # recuperar y eliminar el último stash
git stash apply stash@{2} # aplicar un stash concreto sin eliminarlo
3.3 Flujos de trabajo (workflows) con Git
Gitflow
Workflow estructurado con ramas de larga duración para proyectos con ciclos de release bien definidos:
main– código en producción, siempre estable y etiquetado.develop– rama de integración de features.feature/*– nuevas funcionalidades (se crean desdedevelop, se mergean adevelop).release/*– preparación de versión (correcciones menores, bump de versión).hotfix/*– correcciones urgentes en producción (se crean desdemain, se mergean amainydevelop).
GitHub Flow / Trunk-Based Development
- Solo existe
maincomo rama principal de larga duración. - Las ramas de feature son de corta duración (horas o días).
- Pull Request → revisión de código → CI en verde → merge a main.
- Ideal para despliegue continuo: cada merge a main puede activar un despliegue a producción.
Resolución de conflictos
Un conflicto ocurre cuando dos ramas modifican las mismas líneas de un archivo. Git marca el conflicto y el desarrollador debe resolverlo manualmente:
<<<<<<< HEAD
código de la rama activa actualmente
=======
código de la rama que se está fusionando
>>>>>>> otra-rama
Tras resolver, se eliminan los marcadores y se confirma un commit de resolución.
3.4 Merge vs. Rebase
| Operación | Resultado en el historial | Cuándo usarla |
|---|---|---|
| merge | Crea un commit de merge; conserva el historial tal como ocurrió | Para integrar ramas de larga duración; preserva el historial real |
| rebase | Reaplica los commits sobre una nueva base; historial lineal | Para limpiar el historial de una feature branch antes del merge |
| merge --squash | Comprime todos los commits de la rama en uno solo | Para mantener main con un historial muy limpio |
Regla de oro del rebase: nunca se deben rebasear commits que ya han sido publicados en un repositorio compartido, ya que reescribe el historial y puede romper el trabajo de otros desarrolladores.
3.5 Comandos avanzados de Git
# Rebase
git rebase main # reaplica los commits de la rama actual sobre main
git rebase -i HEAD~3 # rebase interactivo de los últimos 3 commits
# (permite squash, reorder, editar mensajes, drop)
# Cherry-pick: aplica un commit concreto de otra rama a la rama activa
git cherry-pick HASH # aplica el commit indicado
git cherry-pick A..B # aplica el rango de commits de A a B
# Bisect: búsqueda binaria para encontrar el commit que introdujo un bug
git bisect start
git bisect bad # el commit actual contiene el bug
git bisect good v1.0.0 # este commit funcionaba correctamente
# Git hace checkout de commits intermedios hasta localizar el culpable
git bisect reset # terminar la sesión de bisect
# Blame: ver quién modificó cada línea de un archivo y en qué commit
git blame archivo.py
# Reflog: historial local de movimientos de HEAD (para recuperar commits perdidos)
git reflog
git checkout HEAD@{5} # ir a un estado anterior del repositorio
4. Generación de código y documentación
4.1 Generación de código
Herramientas de generación
| Herramienta | Descripción |
|---|---|
| Scaffolding | Genera estructura inicial del proyecto (Angular CLI, Spring Initializr, create-react-app) |
| ORM / generadores de mapeo | Genera clases desde el esquema de BD (Hibernate, Entity Framework, JPA) |
| Generadores de API | Genera código cliente y servidor desde especificación OpenAPI/Swagger |
| Compiladores / transpiladores | TypeScript → JavaScript, SASS/LESS → CSS, Kotlin → JVM bytecode |
| Plantillas (templates) | Freemarker, Thymeleaf, Mustache, Jinja2 |
| Linters y formatters | ESLint, Prettier, Checkstyle, Black; garantizan calidad y estilo homogéneo |
Integración Continua (CI) y Entrega Continua (CD)
- CI (Continuous Integration): cada push activa automáticamente la compilación, análisis de código y ejecución de pruebas. Detecta errores de integración en minutos.
- CD (Continuous Delivery): el artefacto resultado está siempre listo para desplegar; el despliegue final puede requerir aprobación manual.
- CD (Continuous Deployment): cada cambio validado se despliega automáticamente en producción sin intervención humana.
Herramientas: Jenkins, GitHub Actions, GitLab CI/CD, Azure DevOps, Travis CI, CircleCI.
Fases típicas de un pipeline CI/CD
Commit → Build → Static Analysis → Unit Tests → Integration Tests → Security Scan
→ Package → Deploy Staging → Acceptance Tests → Deploy Production
| Fase | Herramientas habituales |
|---|---|
| Build | Maven, Gradle, npm, Make |
| Static analysis | SonarQube, ESLint, Checkstyle |
| Unit tests | JUnit, pytest, Jest |
| Integration tests | TestContainers, Postman/Newman |
| Security scan | OWASP Dependency-Check, Snyk, Trivy |
| Package | Docker, JAR/WAR |
| Deploy | Kubernetes, Ansible, Terraform |
4.2 Documentación del código
Javadoc (Java)
/**
* Calcula el área de un círculo.
*
* @param radio El radio del círculo (debe ser positivo).
* @return El área calculada en unidades cuadradas.
* @throws IllegalArgumentException si el radio es negativo.
* @since 1.0
* @see Math#PI
*/
public double calcularArea(double radio) {
if (radio < 0) throw new IllegalArgumentException("Radio negativo");
return Math.PI * radio * radio;
}
Docstrings (Python)
def calcular_area(radio: float) -> float:
"""
Calcula el área de un círculo.
Args:
radio: El radio del círculo (debe ser positivo).
Returns:
El área calculada en unidades cuadradas.
Raises:
ValueError: Si el radio es negativo.
Example:
>>> calcular_area(5.0)
78.53981633974483
"""
Herramientas de documentación
| Herramienta | Lenguaje / Ámbito |
|---|---|
| Javadoc | Java – genera HTML desde comentarios /** */ |
| Sphinx / pdoc | Python – admite reStructuredText y Markdown |
| JSDoc | JavaScript / TypeScript |
| Doxygen | C, C++, y otros lenguajes |
| Swagger / OpenAPI | APIs REST – documentación interactiva |
| ReadTheDocs | Publicación de documentación técnica online |
| MkDocs / AsciiDoc | Documentación de proyectos en general |
4.3 Versionado semántico (SemVer)
El versionado semántico, definido en semver.org, establece un formato MAJOR.MINOR.PATCH:
| Campo | Cuándo se incrementa |
|---|---|
| MAJOR | Cambio incompatible con la API anterior (breaking change) |
| MINOR | Nueva funcionalidad compatible hacia atrás |
| PATCH | Corrección de errores compatible hacia atrás |
Ejemplos:
1.0.0→ primera versión estable.1.1.0→ nueva funcionalidad sin romper nada.1.1.1→ corrección de un bug.2.0.0→ cambio de API incompatible con la versión 1.x.1.0.0-beta.1→ pre-release (alpha, beta, rc).
El CHANGELOG.md documenta qué cambia entre versiones. Su mantenimiento es una buena práctica fundamental en proyectos open source y corporativos.
5. Metodologías de desarrollo de software
5.1 Metodologías tradicionales (predictivas)
Cascada (Waterfall)
Fases secuenciales y sin solapamiento. Cada fase debe completarse antes de iniciar la siguiente:
- Requisitos → 2. Análisis → 3. Diseño → 4. Implementación → 5. Pruebas → 6. Despliegue → 7. Mantenimiento
Ventajas: sencilla de gestionar, documentación exhaustiva, adecuada para proyectos con requisitos estables y bien conocidos desde el inicio.
Inconvenientes: extremadamente inflexible ante cambios; los errores de análisis se descubren en la fase de pruebas, lo que los hace muy costosos de corregir.
Modelo en V
Extiende la cascada asociando simétricamente cada fase de desarrollo con su fase de pruebas correspondiente. Las pruebas se planifican en paralelo al diseño, no al final:
Requisitos del sistema ←→ Pruebas de aceptación (UAT)
Diseño del sistema ←→ Pruebas del sistema
Diseño de componentes ←→ Pruebas de integración
Codificación → Pruebas unitarias
Ventaja clave frente a cascada: las pruebas se diseñan desde el principio, no como una actividad de última hora.
Modelo en Espiral (Boehm, 1986)
Combina iteración con análisis de riesgos en cada ciclo. Cada vuelta de la espiral consta de cuatro cuadrantes:
- Planificación: objetivos, restricciones, alternativas.
- Análisis de riesgos: identificación y mitigación de riesgos técnicos.
- Ingeniería: desarrollo y pruebas del incremento del ciclo.
- Evaluación del cliente: revisión del incremento y planificación de la siguiente espiral.
Adecuado para proyectos grandes con incertidumbre significativa.
RUP (Rational Unified Process)
- Iterativo, incremental y orientado a la arquitectura.
- 4 fases: Inicio (Inception), Elaboración (Elaboration), Construcción (Construction), Transición (Transition).
- Cada fase contiene varias iteraciones con entregables definidos.
- Usa artefactos UML (diagramas de clases, secuencia, casos de uso, etc.).
- Muy orientado a proyectos empresariales grandes y complejos.
5.2 Metodologías ágiles
El Manifiesto Ágil (2001) fue firmado por 17 expertos y establece 4 valores y 12 principios:
- Individuos e interacciones por encima de procesos y herramientas.
- Software funcionando por encima de documentación exhaustiva.
- Colaboración con el cliente por encima de negociación de contratos.
- Respuesta al cambio por encima de seguir un plan.
Importante: el Manifiesto no dice que los elementos de la derecha no tengan valor; dice que los de la izquierda se valoran más.
Scrum
| Elemento | Descripción |
|---|---|
| Sprint | Iteración de 1-4 semanas con entregable potencialmente funcional |
| Product Backlog | Lista priorizada de todas las funcionalidades del producto |
| Sprint Backlog | Tareas del sprint actual seleccionadas del Product Backlog |
| Incremento | Resultado de cada sprint: software funcional que cumple la DoD |
| Sprint Planning | Reunión de inicio del sprint: selección y descomposición de tareas |
| Daily Scrum | Reunión diaria de 15 min: ¿qué hice ayer? ¿qué haré hoy? ¿impedimentos? |
| Sprint Review | Demostración del incremento al cliente al final del sprint |
| Sprint Retrospective | Reflexión del equipo sobre el proceso: qué mejorar en el siguiente sprint |
| Product Owner (PO) | Representa al cliente; gestiona y prioriza el Product Backlog |
| Scrum Master (SM) | Facilita el proceso, elimina impedimentos, protege al equipo |
| Development Team | Equipo autogestionado y multifuncional que desarrolla el producto |
Métricas de Scrum:
- Velocity: story points completados por sprint; mide la capacidad del equipo y sirve para prever entregas.
- Burn-down chart: gráfica que muestra el trabajo restante en el sprint día a día; permite detectar desviaciones.
- Definition of Done (DoD): criterios acordados que debe cumplir un incremento para considerarse terminado.
- Definition of Ready (DoR): criterios que debe cumplir un ítem del backlog para poder entrar en un sprint.
Kanban
- Visualización del trabajo en un tablero con columnas que representan los estados: Pendiente / En progreso / Revisión / Hecho.
- Límite WIP (Work In Progress): número máximo de tareas simultáneas por columna; reduce el multitasking y mejora el flujo.
- Sin sprints fijos: el trabajo fluye de forma continua.
- Métricas clave: lead time (tiempo desde que se solicita hasta que se entrega) y cycle time (tiempo desde que se empieza hasta que se entrega).
- Muy adecuado para equipos de mantenimiento, soporte y operaciones.
XP (Extreme Programming)
Conjunto de prácticas técnicas intensas orientadas a la calidad del código:
- TDD (Test-Driven Development): los tests se escriben antes que el código.
- Pair programming: dos desarrolladores comparten pantalla y teclado.
- Integración continua: los cambios se integran varias veces al día.
- Refactoring continuo: el código se mejora constantemente sin añadir funcionalidad.
- Diseño simple y YAGNI (You Ain't Gonna Need It): no implementar lo que no se necesita aún.
Comparativa de metodologías
| Cascada | Modelo en V | Scrum | Kanban | XP | |
|---|---|---|---|---|---|
| Planificación | Fija al inicio | Fija al inicio | Por sprint | Continua | Por iteración |
| Cambios | Muy difíciles | Muy difíciles | Cada sprint | En cualquier momento | Bienvenidos |
| Documentación | Extensa | Extensa | Mínima necesaria | Mínima | Mínima |
| Pruebas | Al final | Paralelas al diseño | Continuas | Continuas | Antes del código (TDD) |
| Adecuado para | Requisitos estables | Sistemas críticos | Proyectos con cambios | Mantenimiento / flujo | Equipos pequeños, alta calidad técnica |
6. Pruebas de software
6.1 Objetivos de las pruebas
- Detectar defectos (bugs) lo antes posible.
- Verificar que el software está construido correctamente según el diseño.
- Validar que el software satisface las necesidades reales del usuario.
- Aumentar la confianza en la calidad del producto.
- Proporcionar información para la toma de decisiones de release.
Verificación: ¿estamos construyendo el sistema correctamente? (conforme a la especificación)
Validación: ¿estamos construyendo el sistema correcto? (conforme a la necesidad del usuario)
6.2 Niveles de prueba
Pruebas unitarias (Unit Testing)
- Prueban la unidad mínima de código (función, método, clase) de forma aislada.
- Se usan mocks y stubs para simular dependencias externas (bases de datos, servicios, APIs).
- Son las más rápidas de ejecutar y deben ser las más numerosas (base de la pirámide de pruebas).
- Herramientas: JUnit 5 (Java), Mockito (mocks Java), pytest (Python), Jest (JavaScript).
Pruebas de integración
- Verifican que varios módulos o componentes funcionan correctamente juntos.
- Detectan problemas de interfaz entre módulos (formato de datos incorrecto, errores de comunicación).
- Herramientas: TestContainers, Spring Boot Test, Postman/Newman.
Pruebas de sistema
- Prueban el sistema completo integrado en un entorno similar a producción.
- Verifican el comportamiento frente a los requisitos funcionales y no funcionales (rendimiento, seguridad, usabilidad).
Pruebas de aceptación (UAT – User Acceptance Testing)
- Realizadas por el usuario final o cliente.
- Confirman que el sistema cumple los requisitos del negocio y está listo para producción.
- Criterio de finalización: DoD (Definition of Done).
- En metodologías ágiles pueden automatizarse mediante BDD (Behavior-Driven Development).
6.3 Técnicas de prueba
Caja negra (Black-box Testing)
- No se conoce (o no importa) la implementación interna.
- Se prueba la funcionalidad: entradas → salidas esperadas.
- Técnicas: particiones de equivalencia, valores límite, tablas de decisión, pruebas basadas en estado.
Caja blanca (White-box / Glass-box Testing)
- Se conoce y analiza el código fuente interno.
- Se persigue cubrir el máximo de rutas de ejecución del código.
- Métricas de cobertura:
- Cobertura de líneas (line coverage): % de líneas ejecutadas por los tests.
- Cobertura de ramas (branch coverage): % de ramas condicionales (if/else) cubiertas.
- Cobertura de caminos (path coverage): % de caminos posibles de ejecución (la más completa y costosa).
- Herramientas de cobertura: JaCoCo (Java), Istanbul/nyc (JavaScript), coverage.py (Python).
Caja gris (Grey-box Testing)
- Combinación de caja negra y caja blanca.
- Se conoce la estructura interna pero las pruebas se diseñan desde la perspectiva del usuario.
6.4 Tipos de pruebas por objetivo
| Tipo | Qué verifica |
|---|---|
| Pruebas de regresión | Que los cambios nuevos no rompen funcionalidad existente; se automatizan en CI |
| Pruebas de rendimiento / carga | Comportamiento bajo alta demanda (JMeter, Gatling, k6) |
| Pruebas de estrés | Comportamiento al superar la capacidad máxima del sistema |
| Pruebas de seguridad (Pen Testing) | Vulnerabilidades explotables (OWASP ZAP, Burp Suite) |
| Pruebas de usabilidad | Facilidad de uso para el usuario final |
| Pruebas de accesibilidad | Cumplimiento de estándares WCAG 2.1 |
| Smoke testing | Verificación rápida de que las funciones básicas del sistema arrancan correctamente |
| Pruebas E2E (End-to-End) | Flujo completo de usuario simulando el navegador (Selenium, Cypress, Playwright) |
| Pruebas de mutación | Modifican el código para verificar que los tests detectan los cambios (PIT, Stryker) |
6.5 TDD – Test Driven Development
Ciclo Red → Green → Refactor:
- Red: escribir un test que falle porque la funcionalidad no existe aún. Debe fallar por el motivo correcto.
- Green: escribir el código mínimo para que el test pase. No importa que sea provisional.
- Refactor: mejorar el diseño y la legibilidad del código sin que fallen los tests existentes.
Ventajas: código más simple y desacoplado, alto nivel de cobertura desde el inicio, los tests actúan como documentación viva del comportamiento esperado.
6.6 BDD – Behavior Driven Development
Extensión del TDD que describe el comportamiento del sistema en lenguaje natural comprensible por el cliente, usando la sintaxis Given-When-Then:
Feature: Autenticación de usuario
Scenario: Login correcto
Given el usuario "ana" existe en el sistema
When intenta iniciar sesión con la contraseña correcta
Then debe acceder al panel de control
And ver el mensaje "Bienvenida, Ana"
Scenario: Login con contraseña incorrecta
Given el usuario "ana" existe en el sistema
When intenta iniciar sesión con contraseña incorrecta
Then debe ver el mensaje "Credenciales incorrectas"
Herramientas: Cucumber (Java/Ruby/JavaScript), Behave (Python), SpecFlow (.NET).
6.7 Pirámide de pruebas
La pirámide de pruebas (Mike Cohn) define la proporción ideal de cada tipo de prueba:
/\
/ \ ← E2E / UI Tests (pocas, lentas, más frágiles)
/----\
/ \ ← Integration Tests (algunas, velocidad media)
/--------\
/ \ ← Unit Tests (muchas, rápidas, económicas)
/____________\
- Base (Unit): mayor número, ejecución en milisegundos, coste bajo, aisladas de infraestructura.
- Medio (Integration): número moderado, requieren infraestructura, ejecución en segundos.
- Cima (E2E / UI): pocas, ejecución en minutos, más frágiles y caras de mantener.
El antipatrón contrario se llama pirámide invertida o cono de helado: muchas pruebas de UI y pocas unitarias → suite lenta, frágil y cara.
7. Plataformas de desarrollo colaborativo
7.1 GitHub
- Mayor plataforma mundial de alojamiento de código Git.
- Propiedad de Microsoft (adquirida en 2018).
- Pull Request (PR): mecanismo principal de colaboración; propuesta de cambios para revisión y discusión antes de mergear.
- Issues: gestión de tareas, bugs, mejoras y discusiones del proyecto.
- GitHub Actions: CI/CD integrado mediante ficheros YAML en
.github/workflows/. - GitHub Pages: alojamiento gratuito de sitios estáticos directamente desde el repositorio.
- GitHub Copilot: asistente de código basado en IA (Large Language Model).
- GitHub Codespaces: entorno de desarrollo completo en la nube, accesible desde el navegador.
- GitHub Packages: registro de artefactos (npm, Maven, Docker, etc.) integrado.
- Dependabot: bot que detecta dependencias vulnerables y propone actualizaciones automáticas.
- CodeQL y Secret Scanning: análisis de seguridad integrado en el repositorio.
7.2 GitLab
- Disponible como SaaS (gitlab.com) y como instalación on-premise en servidores propios.
- CI/CD nativo muy completo, configurado mediante el fichero
.gitlab-ci.yml. - Pipeline con stages (build, test, deploy) y environments (staging, production).
- Container Registry integrado para imágenes Docker.
- GitLab Pages para publicar documentación o sitios estáticos.
- Gestión de proyectos completa: wikis, tableros Kanban, milestones y epics.
- Muy usado en la Administración Pública y entornos corporativos por ofrecer control total del código mediante despliegue on-premise.
7.3 Bitbucket
- Propiedad de Atlassian (misma empresa que Jira y Confluence).
- Integración nativa con Jira para vincular commits y Pull Requests a tareas del proyecto.
- Bitbucket Pipelines: CI/CD integrado, configurado con
bitbucket-pipelines.yml. - Compatible originalmente con Git y Mercurial (Mercurial fue descontinuado en 2020).
- Muy usado en entornos empresariales con el ecosistema Atlassian completo (Jira + Confluence + Bitbucket).
7.4 Otras herramientas del ciclo de vida
| Herramienta | Tipo | Descripción |
|---|---|---|
| Jira | Gestión de proyectos | Seguimiento de tareas, sprints, backlog, tableros Kanban/Scrum |
| Confluence | Documentación | Wiki corporativa integrada con Jira |
| SonarQube | Calidad de código | Análisis estático: code smells, cobertura, vulnerabilidades, duplicaciones |
| Jenkins | CI/CD | Servidor de automatización open-source; altamente extensible con plugins |
| Docker Hub | Registro de contenedores | Repositorio de imágenes Docker públicas y privadas |
| Nexus / Artifactory | Repositorios de artefactos | Maven, npm, Docker, Helm charts; proxy de dependencias externas |
| Azure DevOps | Suite DevOps completa | Repos, Boards, Pipelines, Artifacts, Test Plans; integrado con Azure |
7.5 Funcionalidades colaborativas clave
| Función | Descripción |
|---|---|
| Fork | Copia independiente de un repositorio en tu cuenta; base del modelo open source |
| Pull Request / Merge Request | Solicitud para integrar cambios tras revisión y aprobación |
| Code review | Revisión del código por otro/s desarrolladores antes de mergear |
| Branch protection | Impide push directo a ramas protegidas (main, develop); obliga a PR y CI en verde |
| Webhooks | Notificaciones HTTP automáticas a servicios externos ante cada evento (push, PR…) |
| Wiki | Documentación del proyecto integrada en la plataforma |
| Milestones | Agrupación de issues y PRs para seguimiento de versiones o fechas de entrega |
| Labels / etiquetas | Clasificación de issues y PRs: bug, enhancement, documentation… |
8. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|---|---|
| DVCS | Control de versiones distribuido; cada clon tiene el historial completo |
| Git | DVCS más usado; objetos SHA-1; historial en forma de DAG |
| Commit | Instantánea identificada por hash SHA-1; apunta a su(s) padre(s) |
| Branch | Línea de desarrollo paralela; main es la rama principal por convención |
| Merge vs Rebase | Merge preserva el historial real; Rebase lo lineariza (no rebasear commits publicados) |
| Gitflow | main + develop + feature/* + release/* + hotfix/* |
| .gitignore | Archivo que define qué ficheros excluir del control de versiones |
| CI/CD | CI: integración continua; CD: entrega/despliegue continuo (Jenkins, Actions, GitLab CI) |
| SemVer | MAJOR.MINOR.PATCH; MAJOR = breaking change, MINOR = nueva feature, PATCH = bugfix |
| Cascada | Fases secuenciales sin retroceso; errores se detectan tarde |
| Modelo en V | Cascada + pruebas planificadas simétricamente desde el diseño |
| Manifiesto Ágil | 2001; 4 valores: individuos, software funcionando, colaboración, respuesta al cambio |
| Scrum | Sprints 1-4 semanas; PO, SM, Dev Team; Planning, Daily, Review, Retrospective |
| Velocity | Story points completados por sprint; mide capacidad del equipo |
| DoD | Definition of Done: criterios de terminado de un incremento en Scrum |
| Kanban | Tablero visual, límites WIP; métricas: lead time y cycle time |
| TDD | Red → Green → Refactor; el test se escribe antes que el código |
| BDD | Given-When-Then; comportamiento en lenguaje natural; Cucumber, Behave |
| Prueba unitaria | Unidad mínima de forma aislada; mocks/stubs para dependencias |
| Prueba de integración | Varios módulos juntos; detecta problemas de interfaz |
| Prueba de aceptación (UAT) | La realiza el usuario final; criterio: DoD |
| Caja negra | Funcionalidad sin ver el código; particiones de equivalencia, valores límite |
| Caja blanca | Conociendo el código; cobertura de líneas, ramas y caminos |
| Pirámide de pruebas | Base: unitarias (muchas); medio: integración; cima: E2E (pocas) |
| Pull Request | Propuesta de cambios para revisión antes de mergear |
| GitHub | Plataforma más popular; Microsoft (2018); Actions para CI/CD; Copilot IA |
| GitLab | On-premise; muy usada en Administración Pública; CI/CD con .gitlab-ci.yml |
| Bitbucket | Atlassian; integración nativa con Jira |
| SonarQube | Análisis estático de calidad del código: code smells, cobertura, vulnerabilidades |