La integración continua es fundamental para equipos de desarrollo modernos. Antes de sumergirte en Bitbucket Pipelines, te recomendamos revisar nuestra guía de optimización de pipelines CI/CD para equipos QA para entender las mejores prácticas generales, explorar cómo una estrategia de automatización de pruebas sólida maximiza el valor de tu pipeline, y entender las técnicas de diseño de casos de prueba para crear tests efectivos que ejecutar en CI.

Al final de este tutorial, tendrás una configuración completamente funcional de Bitbucket Pipelines que ejecuta pruebas automáticamente en cada commit. En solo 45 minutos, configurarás un pipeline CI/CD que detecta errores antes de llegar a producción, con testing paralelo, caché y estrategias de despliegue.

Lo Que Construirás

Crearás un pipeline de testing listo para producción que:

  • Ejecuta automáticamente pruebas unitarias, de integración y E2E en cada push
  • Ejecuta pruebas en paralelo para reducir el tiempo de build en 60%
  • Almacena en caché las dependencias para acelerar los builds
  • Genera reportes de cobertura de pruebas
  • Despliega automáticamente cuando todas las pruebas pasan

Esta configuración es utilizada por empresas como Atlassian, Docker y miles de equipos de desarrollo para mantener la calidad del código y entregar más rápido.

Objetivos de Aprendizaje

En este tutorial aprenderás:

  • Cómo configurar bitbucket-pipelines.yml para testing automatizado
  • Cómo configurar ejecución de pruebas en paralelo para feedback más rápido
  • Cómo implementar estrategias de caché para optimizar tiempos de build
  • Cómo integrar reportes de cobertura y quality gates
  • Cómo manejar diferentes entornos (staging, producción)
  • Cómo solucionar problemas comunes del pipeline

Tiempo Estimado: 45-60 minutos

Prerequisitos

Software Requerido

Antes de comenzar, instala:

HerramientaVersiónPropósito
Git2.0+Control de versiones
Node.js18+Runtime para el proyecto ejemplo
npm9+Gestión de paquetes
Docker20+Runtime de contenedores (opcional)

Instalación:

# macOS
brew install git node

# Linux (Ubuntu/Debian)
apt-get install git nodejs npm

# Windows
choco install git nodejs

Conocimientos Requeridos

Debes estar familiarizado con:

  • ✅ Flujos básicos de Git (commit, push, pull)
  • ✅ Fundamentos de línea de comandos
  • ✅ Comprensión básica de conceptos CI/CD
  • ❌ No requerido: Conocimiento avanzado de Docker o Kubernetes

Recursos Requeridos

  • Cuenta de Bitbucket (tier gratuito funciona)
  • Un repositorio con pruebas (o usa nuestro proyecto ejemplo)
  • Acceso de escritura a configuración del repositorio
  • 15 minutos para ejecución inicial del pipeline

Paso 1: Configuración del Proyecto

En este paso, crearemos el archivo de configuración del pipeline y entenderemos su estructura.

Crear Configuración del Pipeline

Navega a la raíz de tu repositorio y crea el archivo de configuración:

cd tu-proyecto
touch bitbucket-pipelines.yml

Agrega la estructura básica del pipeline:

# bitbucket-pipelines.yml
image: node:18

pipelines:
  default:

    - step:
        name: Build and Test
        caches:

          - node
        script:

          - npm install
          - npm test

Lo que hace esto:

  • image: node:18 - Especifica la imagen Docker para el entorno de build
  • caches: - node - Cachea node_modules para acelerar builds subsecuentes
  • script - Comandos ejecutados en secuencia

Commit y Push

git add bitbucket-pipelines.yml
git commit -m "Add Bitbucket Pipelines configuration"
git push origin main

Deberías ver:

  • Bitbucket detecta automáticamente la configuración
  • La primera ejecución del pipeline comienza en 30 segundos
  • El pipeline aparece en la UI de Bitbucket en la pestaña “Pipelines”

💡 Consejo Pro: Habilita Pipelines en Configuración del Repositorio → Pipelines → Configuración si aún no está habilitado.

Verificar Configuración

Navega a tu repositorio en Bitbucket y haz clic en la pestaña “Pipelines”.

Resultado esperado:

✅ Pipeline #1 (en progreso)
   └── Build and Test (ejecutando)

Punto de Control: Ahora deberías tener un pipeline básico ejecutándose. Incluso si las pruebas fallan, el pipeline debería ejecutarse.

Paso 2: Configurar Múltiples Tipos de Pruebas

Los proyectos del mundo real necesitan diferentes tipos de pruebas. Configuremos pruebas unitarias, de integración y linting en paralelo.

Actualizar Configuración del Pipeline

Modifica tu bitbucket-pipelines.yml:

image: node:18

definitions:
  caches:
    npm: ~/.npm

pipelines:
  default:

    - parallel:
      - step:
          name: Unit Tests
          caches:

            - node
            - npm
          script:

            - npm ci
            - npm run test:unit
          artifacts:

            - coverage/**

      - step:
          name: Linting
          caches:

            - node
          script:

            - npm ci
            - npm run lint

      - step:
          name: Integration Tests
          caches:

            - node
          services:

            - docker
          script:

            - npm ci
            - npm run test:integration

Lo que cambió:

  • parallel: - Ejecuta múltiples pasos simultáneamente (60% más rápido)
  • npm ci - Instalación limpia, más rápida y confiable que npm install
  • artifacts - Guarda reportes de cobertura para pasos posteriores
  • services: - docker - Inicia el daemon de Docker para pruebas de integración

Actualizar Scripts de package.json

Asegúrate de que tu package.json tenga los scripts de prueba:

{
  "scripts": {
    "test:unit": "jest --coverage --testPathPattern=unit",
    "test:integration": "jest --testPathPattern=integration",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  }
}

Problemas Comunes ⚠️

Problema: “npm run test:unit not found”

Solución: Agrega el script faltante a package.json o actualiza el comando del pipeline para coincidir con tu comando de prueba real:

script:

  - npm ci
  - npm test  # Usa tu comando de prueba real

Problema: Errores de memoria insuficiente durante las pruebas

Solución: Aumenta la asignación de memoria:

- step:
    name: Unit Tests
    size: 2x  # Duplica la memoria (4GB en lugar de 2GB)

Verificar Este Paso

Haz push de tus cambios y monitorea el pipeline:

git add bitbucket-pipelines.yml package.json
git commit -m "Add parallel test execution"
git push

Resultado esperado:

✅ Pipeline #2 (en progreso)
   ├── Unit Tests (ejecutando) [30s]
   ├── Linting (ejecutando) [15s]
   └── Integration Tests (ejecutando) [45s]

Punto de Control: Los tres pasos de prueba deberían ejecutarse simultáneamente, reduciendo el tiempo total de ejecución.

Paso 3: Implementar Caché Avanzado

El caché reduce drásticamente los tiempos de build. Implementemos caché multicapa.

Estrategia de Caché Mejorada

Actualiza el pipeline con caché avanzado:

image: node:18

definitions:
  caches:
    npm: ~/.npm
    cypress: ~/.cache/Cypress
    jest: .jest-cache

pipelines:
  default:

    - parallel:
      - step:
          name: Unit Tests
          caches:

            - node
            - npm
            - jest
          script:

            - npm ci --cache ~/.npm --prefer-offline
            - npm run test:unit -- --cache --cacheDirectory=.jest-cache
          artifacts:

            - coverage/**
            - test-results/**

Beneficios del caché:

  • Primer build: ~120 segundos (sin caché)
  • Builds subsecuentes: ~35 segundos (con caché)
  • Ahorro: 70% builds más rápidos

💡 Consejo Pro: Cachea capas de Docker para builds aún más rápidos:

- step:
    name: Build Docker Image
    caches:

      - docker
    script:

      - docker build -t myapp:$BITBUCKET_COMMIT .

Verificar que el Caché Funciona

Revisa los logs del pipeline para indicadores de caché:

Restoring caches...
✓ node: Restored successfully (142.3 MB)
✓ npm: Restored successfully (89.1 MB)

Punto de Control: El segundo build debería ser 50-70% más rápido que el primero.

Paso 4: Agregar Cobertura de Pruebas y Quality Gates

Asegura la calidad del código agregando umbrales de cobertura.

Configurar Reportes de Cobertura

Agrega configuración de cobertura a jest.config.js:

// jest.config.js
module.exports = {
  collectCoverage: true,
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov', 'html'],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  }
};

Actualizar Pipeline con Quality Gates

- step:
    name: Unit Tests with Coverage
    caches:

      - node
    script:

      - npm ci
      - npm run test:unit
      - |
        if [ -f coverage/lcov.info ]; then
          echo "✅ Coverage report generated"
        else
          echo "❌ Coverage report missing"
          exit 1
        fi
    artifacts:

      - coverage/**

Lo que hace esto:

  • Genera reportes de cobertura en múltiples formatos
  • Falla el build si la cobertura cae por debajo del 80%
  • Guarda artefactos de cobertura para revisión posterior

Integración con Herramientas de Cobertura de Código

Agrega integración con Codecov:

- step:
    name: Upload Coverage
    script:

      - pipe: codecov/codecov-upload:1.3.2
        variables:
          CODECOV_TOKEN: $CODECOV_TOKEN

Salida esperada:

✅ Coverage: 87.3% (+2.1%)
✅ All thresholds passed
✅ Uploaded to Codecov

Punto de Control: El build debería fallar si la cobertura cae por debajo del 80%.

Paso 5: Pipelines Específicos por Entorno

Configura diferentes comportamientos para ramas y entornos.

Pipelines Específicos por Rama

pipelines:
  default:

    - step:
        name: Quick Tests
        script:

          - npm ci
          - npm run test:unit

  branches:
    main:

      - step:
          name: Full Test Suite
          script:

            - npm ci
            - npm run test:unit
            - npm run test:integration
            - npm run test:e2e
      - step:
          name: Deploy to Staging
          deployment: staging
          script:

            - npm run deploy:staging

    develop:

      - step:
          name: Development Tests
          script:

            - npm ci
            - npm run test:unit
            - npm run lint

  pull-requests:
    '**':

      - step:
          name: PR Validation
          script:

            - npm ci
            - npm run test:unit
            - npm run lint

Comportamiento del pipeline:

  • Ramas de features: Solo pruebas unitarias rápidas (2 minutos)
  • Pull requests: Pruebas unitarias + linting (3 minutos)
  • Rama develop: Pruebas de desarrollo (4 minutos)
  • Rama main: Suite completa + despliegue (8 minutos)

Variables de Entorno

Agrega secretos en Configuración del Repositorio → Pipelines → Variables del repositorio:

- step:
    name: Integration Tests
    script:

      - export DATABASE_URL=$DATABASE_URL_TEST
      - export API_KEY=$API_KEY_TEST
      - npm run test:integration

💡 Consejo Pro: Usa variables de despliegue para configuraciones específicas del entorno:

- step:
    name: Deploy to Production
    deployment: production
    script:

      - echo "Deploying with API_KEY: ${API_KEY}"
      - npm run deploy

Punto de Control: Diferentes ramas deberían activar diferentes configuraciones de pipeline.

Paso 6: Manejar Despliegue

Despliega automáticamente cuando las pruebas pasan.

Despliegue Condicional

- step:
    name: Deploy to Production
    deployment: production
    trigger: manual
    script:

      - pipe: atlassian/aws-s3-deploy:1.1.0
        variables:
          AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
          AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
          AWS_DEFAULT_REGION: 'us-east-1'
          S3_BUCKET: 'my-production-bucket'
          LOCAL_PATH: 'dist'

Opciones de despliegue:

  • trigger: manual - Requiere aprobación manual
  • trigger: automatic - Despliega automáticamente cuando las pruebas pasan

Despliegue con Rollback

- step:
    name: Deploy with Rollback
    script:

      - export PREVIOUS_VERSION=$(git describe --tags --abbrev=0)
      - npm run deploy
      - npm run healthcheck || (echo "Health check failed, rolling back..." && git checkout $PREVIOUS_VERSION && npm run deploy && exit 1)

Punto de Control: El despliegue solo debería ocurrir después de que todas las pruebas pasen.

Probar Tu Implementación

Ahora verifiquemos que todo funciona correctamente.

Pruebas Manuales

  1. Caso de Prueba 1: Push a Rama de Feature

    Crea y haz push a una rama de feature:

    git checkout -b feature/test-pipeline
    git push origin feature/test-pipeline
    

    Resultado esperado:

    ✅ Quick Tests passed (2m 15s)
    
  2. Caso de Prueba 2: Pull Request

    Crea un PR en la UI de Bitbucket.

    Resultado esperado:

    ✅ PR Validation passed (3m 30s)
    ├── Unit Tests ✅
    └── Linting ✅
    
  3. Caso de Prueba 3: Despliegue a Rama Main

    Merge a main:

    git checkout main
    git merge feature/test-pipeline
    git push origin main
    

    Resultado esperado:

    ✅ Full Test Suite passed (7m 45s)
    ⏸️  Deploy to Staging (trigger manual disponible)
    

Script Automatizado de Verificación de Salud

Crea un script de validación:

#!/bin/bash
# validate-pipeline.sh

echo "🔍 Validando Configuración de Bitbucket Pipeline..."

# Verificar si existe el archivo del pipeline
if [ ! -f "bitbucket-pipelines.yml" ]; then
    echo "❌ bitbucket-pipelines.yml no encontrado"
    exit 1
fi
echo "✅ Configuración del pipeline existe"

# Validar sintaxis YAML
if command -v yamllint &> /dev/null; then
    yamllint bitbucket-pipelines.yml || exit 1
    echo "✅ Sintaxis YAML válida"
fi

# Verificar scripts requeridos en package.json
required_scripts=("test:unit" "lint")
for script in "${required_scripts[@]}"; do
    if grep -q "\"$script\"" package.json; then
        echo "✅ Script '$script' encontrado"
    else
        echo "❌ Script '$script' faltante"
        exit 1
    fi
done

echo "✅ ¡Todas las validaciones pasaron! 🎉"

Ejecútalo:

chmod +x validate-pipeline.sh
./validate-pipeline.sh

Lista de Verificación de Validación

  • Pipeline se ejecuta en cada push
  • Pasos paralelos se ejecutan simultáneamente
  • Caché reduce tiempos de build subsecuentes
  • Reportes de cobertura generados
  • Comportamiento específico por rama funciona
  • Despliegue manual requiere aprobación
  • Pruebas fallidas bloquean despliegue

Solución de Problemas

Problema 1: Pipeline No Se Activa

Síntomas:

  • No se ejecuta ningún pipeline después del push
  • La pestaña “Pipelines” no muestra historial

Causas Posibles:

  1. Pipelines no habilitado en configuración del repositorio
  2. Sintaxis YAML inválida en archivo de configuración

Solución:

# Validar sintaxis YAML localmente
docker run --rm -v $(pwd):/work mikefarah/yq eval bitbucket-pipelines.yml

# Habilitar pipelines en configuración del repositorio
# Navegar a: Configuración del Repositorio → Pipelines → Configuración
# Activar "Enable Pipelines"

Cómo verificar que está arreglado:

git commit --allow-empty -m "Trigger pipeline"
git push
# Revisar pestaña Pipelines en 30 segundos

Problema 2: Errores de Memoria Insuficiente

Mensaje de error:

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

Lo que significa: Tus pruebas están consumiendo más del límite de memoria predeterminado de 2GB.

Solución rápida:

- step:
    name: Memory-Intensive Tests
    size: 2x  # Aumenta a 4GB RAM
    script:

      - npm ci
      - NODE_OPTIONS="--max-old-space-size=3072" npm test

Solución detallada:

  1. Perfila tus pruebas para encontrar fugas de memoria:

    node --inspect-brk node_modules/.bin/jest --runInBand
    
  2. Optimiza configuración de pruebas:

    // jest.config.js
    module.exports = {
      maxWorkers: 2,  // Limita workers paralelos
      clearMocks: true,
      resetMocks: true,
    };
    

Problema 3: Tiempos de Build Lentos

Si los builds toman más de 5 minutos:

  1. Habilita ejecución paralela:

    - parallel:
      - step:
          name: Fast Tests
      - step:
          name: More Tests
    
  2. Optimiza caché:

    definitions:
      caches:
        custom-cache: path/to/cache
    
  3. Usa npm ci en lugar de npm install:

    npm ci  # 40% más rápido que npm install
    
  4. Monitorea métricas de build:

    # Agregar al pipeline
    - time npm ci
    - time npm test
    

Problema 4: Fallos de Conexión al Servicio Docker

Síntomas:

  • Pruebas de integración fallan con “Cannot connect to Docker daemon”

Solución:

- step:
    name: Integration Tests
    services:

      - docker
    script:

      - sleep 10  # Esperar a que Docker inicie
      - docker ps  # Verificar que Docker está ejecutando
      - npm run test:integration

¿Aún Tienes Problemas?

Siguientes Pasos

¡Felicitaciones! Has configurado exitosamente testing automatizado en Bitbucket Pipelines. 🎉

Lo Que Has Construido

Ahora tienes:

  • ✅ Testing automatizado en cada commit
  • ✅ Ejecución de pruebas en paralelo (60% builds más rápidos)
  • ✅ Estrategia de caché multicapa
  • ✅ Reportes de cobertura con quality gates
  • ✅ Comportamiento de pipeline específico por rama
  • ✅ Controles de despliegue manual
  • ✅ Pipeline CI/CD listo para producción

Mejora Tus Habilidades

¿Listo para más? Prueba estas mejoras:

Mejoras Fáciles (30 min cada una)

  1. Agregar Notificaciones de Slack

    - step:
        name: Notify on Failure
        script:
    
          - pipe: atlassian/slack-notify:2.1.0
            variables:
              WEBHOOK_URL: $SLACK_WEBHOOK
    
  2. Agregar Escaneo de Seguridad

    - step:
        name: Security Audit
        script:
    
          - npm audit --audit-level=moderate
    

Mejoras Intermedias (1-2 horas cada una)

  1. Agregar Testing de Performance

    • Integrar Lighthouse CI
    • Establecer presupuestos de performance
    • Fallar builds en regresión
  2. Implementar Despliegue Blue-Green

    • Desplegar a entorno staging
    • Ejecutar smoke tests
    • Cambiar a producción

Mejoras Avanzadas (3+ horas)

  1. Despliegue Multi-Cloud
    • Desplegar a AWS, Azure, GCP simultáneamente
    • Enrutamiento geográfico
    • Estrategias de failover

Tutoriales Relacionados

Continúa aprendiendo:

Comparte Tus Resultados

¿Construiste un pipeline impresionante? Compártelo:

  • Tuitea tu configuración con #BitbucketPipelines
  • Escribe sobre tu experiencia en tu blog
  • Contribuye mejoras a proyectos open-source

Conclusión

Lo Que Lograste

En este tutorial:

  1. ✅ Creaste una configuración completa de Bitbucket Pipelines
  2. ✅ Implementaste ejecución de pruebas en paralelo para feedback más rápido
  3. ✅ Configuraste caché multicapa para optimizar tiempos de build
  4. ✅ Agregaste reportes de cobertura y quality gates
  5. ✅ Configuraste comportamientos de pipeline específicos por rama
  6. ✅ Configuraste despliegue condicional con controles manuales

Conclusiones Clave

  • Ejecución paralela puede reducir tiempos de build en 50-70%
  • Estrategias de caché son críticas para ciclos de feedback rápidos
  • Quality gates previenen que código de baja calidad llegue a producción
  • Configuraciones específicas por rama balancean velocidad y exhaustividad
  • Triggers de despliegue manual proporcionan seguridad para releases de producción

Sigue Aprendiendo

¡Esto es solo el comienzo! Consulta:


¿Preguntas o comentarios? Comparte tu configuración de pipeline en los comentarios abajo!

¿Te resultó útil? ¡Compártelo con tu equipo para mejorar vuestro flujo CI/CD!

Ver También

Recursos Oficiales