Introducción a la Documentación de Pruebas de Migración

Las pruebas de migración son una de las actividades más críticas y propensas a riesgos en ingeniería de software. Ya sea migrando datos entre bases de datos, transicionando a nuevas plataformas, actualizando sistemas o moviéndose a la nube, una documentación completa de pruebas asegura la integridad de datos, funcionalidad del sistema y continuidad del negocio durante la transición.

Esta guía proporciona marcos detallados, plantillas y estrategias del mundo real para documentar pruebas de migración que minimizan riesgos y aseguran transiciones exitosas de sistemas.

Tipos de Migraciones y Enfoques de Pruebas

Escenarios Comunes de Migración

Migraciones de Datos:

  • Cambios de plataforma de base de datos (Oracle → PostgreSQL)
  • Migraciones de centro de datos
  • Retiro de sistemas legacy
  • Consolidación y deduplicación de datos

Migraciones de Aplicaciones:

  • Modernización de plataforma (Monolito → Microservicios)
  • Migraciones a la nube (On-premise → AWS/Azure/GCP)
  • Actualizaciones de framework (Angular 8 → Angular 17)
  • Actualizaciones de versión (Java 11 → Java 21)

Migraciones de Infraestructura:

  • Migraciones de servidores
  • Cambios de infraestructura de red
  • Transiciones de sistemas de almacenamiento
  • Virtualización y containerización

Evaluación de Riesgos de Migración

Categoría de RiesgoImpactoProbabilidadEstrategia de Mitigación
Pérdida de DatosCríticoMedioBackups completos, checksums de validación, plan de rollback
Corrupción de DatosCríticoMedioVerificaciones de integridad, validación de transformaciones
Tiempo de Inactividad ExcedidoAltoAltoMigración por fases, ejecución paralela, ensayo de cutover
Degradación de RendimientoAltoMedioPruebas de carga, planificación de capacidad, optimización
Fallos de IntegraciónAltoMedioPruebas de API, mapeo de dependencias, smoke tests
Impacto en UsuariosMedioAltoUAT, capacitación, plan de comunicación

Documento de Estrategia de Pruebas de Migración

Plantilla de Estrategia

# ESTRATEGIA DE PRUEBAS DE MIGRACIÓN

## Resumen Ejecutivo
**Proyecto de Migración**: Migración de CRM Legacy a Salesforce
**Fecha de Migración**: 2025-12-15
**Test Manager**: Alex Rodriguez
**Última Actualización**: 2025-10-08

## Visión General de Migración
### Sistema Origen
- **Plataforma**: Aplicación CRM .NET Personalizada
- **Base de Datos**: SQL Server 2016
- **Registros**: 2.5M registros de clientes, 15M transacciones
- **Interfaces**: 12 sistemas integrados
- **Disponibilidad**: Operaciones 24/7

### Sistema Destino
- **Plataforma**: Salesforce Sales Cloud
- **Edición**: Enterprise Edition
- **Personalizaciones**: 45 objetos personalizados, 120 campos personalizados
- **Integraciones**: REST APIs, middleware MuleSoft
- **Rendimiento Esperado**: < 2s carga de página, 10K usuarios concurrentes

## Enfoque de Migración
**Estrategia**: Migración por fases con ejecución paralela

### Fase 1: Migración Piloto (Semana 1-2)
- Migrar 10% de clientes (250K registros)
- Unidad de negocio única (Costa Oeste)
- Pruebas de funcionalidad completa
- Pruebas de aceptación de usuario

### Fase 2: Migración Incremental (Semana 3-6)
- Migrar 90% restante en lotes
- 500K registros por lote
- Validación automatizada después de cada lote
- Monitoreo continuo

### Fase 3: Cutover (Semana 7)
- Migración delta final
- Cambiar DNS/enrutamiento
- Desactivar sistema legacy
- Período de monitoreo de 48 horas

## Objetivos de Pruebas
1. Verificar 100% precisión de migración de datos
2. Validar todos los flujos de trabajo de negocio
3. Confirmar funcionalidad de integración
4. Asegurar rendimiento cumple SLAs
5. Validar seguridad y cumplimiento
6. Verificar reportes y analítica

## Alcance de Pruebas

### En Alcance
- Validación de migración de datos (todas las tablas)
- Pruebas funcionales (journeys críticos de usuario)
- Pruebas de integración (las 12 interfaces)
- Pruebas de rendimiento (carga y estrés)
- Pruebas de seguridad (autenticación, autorización)
- UAT (50 usuarios de negocio)

### Fuera de Alcance
- Corrección de bugs del sistema legacy
- Desarrollo de nuevas características
- Datos históricos mayores a 7 años
- Integraciones retiradas (3 sistemas deprecados)

Pruebas de Migración de Datos

Documento de Mapeo de Datos

## Especificación de Mapeo de Datos

### Mapeo de Datos de Clientes

| Campo Origen | Tipo Origen | Campo Destino | Tipo Destino | Transformación | Regla de Validación |
|-------------|-------------|---------------|--------------|----------------|---------------------|
| CustomerID | INT | Account.CustomerNumber__c | Text(20) | CAST a VARCHAR | NOT NULL, UNIQUE |
| FirstName | VARCHAR(50) | Account.FirstName | Text(40) | TRIM, UPPERCASE primer char | NOT NULL |
| LastName | VARCHAR(50) | Account.LastName | Text(80) | TRIM, UPPERCASE primer char | NOT NULL |
| Email | VARCHAR(100) | Account.Email__c | Email | LOWERCASE, validar formato | Formato email válido |
| PhoneNumber | VARCHAR(20) | Account.Phone | Phone | Formato: (XXX) XXX-XXXX | Formato teléfono válido |
| CreateDate | DATETIME | Account.CreatedDate | DateTime | Convertir a UTC | NOT NULL |
| Status | TINYINT | Account.Status__c | Picklist | 0→Inactivo, 1→Activo | Valor picklist válido |
| CreditLimit | DECIMAL(10,2) | Account.CreditLimit__c | Currency | Mapeo directo | >= 0 |

### Reglas de Transformación de Datos

**Regla 1: Estandarización de Nombres**
```sql
-- Origen
FirstName = ' john ', LastName = ' DOE '

-- Transformación
FirstName = TRIM(INITCAP(FirstName)) -- 'John'
LastName = TRIM(UPPER(LastName)) -- 'DOE'

-- Destino
FirstName = 'John', LastName = 'DOE'

Regla 2: Mapeo de Códigos de Estado

mapeo_estado = {
    0: 'Inactivo',
    1: 'Activo',
    2: 'Suspendido',
    3: 'Pendiente',
    99: 'Eliminado'
}

# Aplicar transformación
estado_destino = mapeo_estado.get(estado_origen, 'Desconocido')

### Marco de Validación de Datos

```python
# Marco de Validación de Datos de Migración

import pandas as pd
from typing import Dict, List, Tuple

class ValidadorMigracion:
    """Validación completa de datos para migraciones"""

    def __init__(self, conexion_origen, conexion_destino):
        self.conexion_origen = conexion_origen
        self.conexion_destino = conexion_destino
        self.resultados_validacion = []

    def validar_conteo_registros(self, mapeo_tablas: Dict[str, str]) -> Dict:
        """
        Validar conteos de registros entre origen y destino

        Args:
            mapeo_tablas: Dict de {tabla_origen: tabla_destino}

        Returns:
            Dict con resultados de validación
        """
        resultados = {}

        for tabla_origen, tabla_destino in mapeo_tablas.items():
            conteo_origen = self._obtener_conteo(self.conexion_origen, tabla_origen)
            conteo_destino = self._obtener_conteo(self.conexion_destino, tabla_destino)

            coincide = conteo_origen == conteo_destino
            resultados[tabla_origen] = {
                'conteo_origen': conteo_origen,
                'conteo_destino': conteo_destino,
                'coincide': coincide,
                'diferencia': conteo_origen - conteo_destino
            }

        return resultados

    def validar_integridad_datos(self, consultas_validacion: List[Tuple]) -> pd.DataFrame:
        """
        Ejecutar consultas de validación de integridad de datos

        Args:
            consultas_validacion: Lista de (descripcion, consulta_origen, consulta_destino)

        Returns:
            DataFrame con resultados de validación
        """
        resultados = []

        for descripcion, consulta_origen, consulta_destino in consultas_validacion:
            resultado_origen = pd.read_sql(consulta_origen, self.conexion_origen)
            resultado_destino = pd.read_sql(consulta_destino, self.conexion_destino)

            # Comparar resultados
            coincide = resultado_origen.equals(resultado_destino)

            resultados.append({
                'validacion': descripcion,
                'valor_origen': resultado_origen.iloc[0, 0] if not resultado_origen.empty else None,
                'valor_destino': resultado_destino.iloc[0, 0] if not resultado_destino.empty else None,
                'estado': 'PASADO' if coincide else 'FALLADO'
            })

        return pd.DataFrame(resultados)

    def validar_integridad_referencial(self, claves_foraneas: Dict) -> Dict:
        """
        Validar que las relaciones de clave foránea se mantienen

        Args:
            claves_foraneas: Dict de definiciones de relaciones

        Returns:
            Dict con resultados de validación
        """
        resultados = {}

        for nombre_relacion, definicion_relacion in claves_foraneas.items():
            # Verificar registros huérfanos en destino
            consulta = f"""
                SELECT COUNT(*) as conteo_huerfanos
                FROM {definicion_relacion['tabla_hijo_destino']}
                WHERE {definicion_relacion['clave_foranea']} NOT IN (
                    SELECT {definicion_relacion['clave_primaria']}
                    FROM {definicion_relacion['tabla_padre_destino']}
                )
            """

            huerfanos = pd.read_sql(consulta, self.conexion_destino).iloc[0, 0]

            resultados[nombre_relacion] = {
                'registros_huerfanos': huerfanos,
                'estado': 'PASADO' if huerfanos == 0 else 'FALLADO'
            }

        return resultados

    def generar_reporte_validacion(self) -> str:
        """Generar reporte completo de validación"""
        reporte = "# REPORTE DE VALIDACIÓN DE MIGRACIÓN\n\n"
        reporte += f"Generado: {datetime.now().isoformat()}\n\n"

        # Agregar todos los resultados de validación
        for tipo_validacion, resultados in self.resultados_validacion:
            reporte += f"## {tipo_validacion}\n\n"
            reporte += resultados.to_markdown() if isinstance(resultados, pd.DataFrame) else str(resultados)
            reporte += "\n\n"

        return reporte


# Ejemplo de Uso
consultas_validacion = [
    (
        "Conteo Total de Clientes",
        "SELECT COUNT(*) FROM Customers WHERE Status = 1",
        "SELECT COUNT(*) FROM Account WHERE Status__c = 'Activo'"
    ),
    (
        "Ingresos Totales",
        "SELECT SUM(Amount) FROM Orders WHERE OrderDate >= '2023-01-01'",
        "SELECT SUM(Amount__c) FROM Order__c WHERE OrderDate__c >= 2023-01-01"
    )
]

# Ejecutar validación
validador = ValidadorMigracion(conexion_origen, conexion_destino)
resultados_integridad = validador.validar_integridad_datos(consultas_validacion)
print(resultados_integridad)

Plan de Rollback de Migración

Estrategia de Rollback

# PLAN DE ROLLBACK DE MIGRACIÓN

## Criterios de Decisión de Rollback

### Severidad 1: Rollback Inmediato
- Pérdida de datos detectada (> 0.1%)
- Fallo de proceso de negocio crítico
- Brecha de seguridad o exposición de datos
- Indisponibilidad completa del sistema
- **Tiempo de Decisión**: < 30 minutos
- **Decisor**: CTO + Líder de Migración

### Severidad 2: Rollback Planificado
- Degradación de rendimiento > 50%
- Funcionalidad principal rota (afectando > 20% usuarios)
- Múltiples fallos de integración
- Problemas de calidad de datos > 5%
- **Tiempo de Decisión**: < 2 horas
- **Decisor**: Comité Directivo del Proyecto

## Procedimientos de Rollback

### Paso 1: Comunicación (0-15 minutos)
```bash
# Ejecutar plan de comunicación
./scripts/send_rollback_notification.sh

# Notificar a stakeholders
- Equipo de ingeniería
- Soporte al cliente
- Usuarios de negocio
- Equipo ejecutivo

Paso 2: Congelar Estado (15-30 minutos)

# Detener toda sincronización de datos
./scripts/stop_sync_services.sh

# Capturar estado actual
./scripts/capture_system_state.sh

# Habilitar modo de mantenimiento
./scripts/enable_maintenance_mode.sh

Paso 3: Restaurar Base de Datos (30-90 minutos)

# Restaurar base de datos origen desde backup
pg_restore --host=source-db.internal \
           --dbname=crm_production \
           --clean --create \
           /backups/pre_migration_backup.dump

# Verificar restauración
./scripts/verify_database_restore.sh

Paso 4: Redirigir Tráfico (90-105 minutos)

# Actualizar DNS/Load balancer
./scripts/redirect_to_legacy.sh

# Verificar enrutamiento
curl -I https://crm.company.com
# Esperado: X-Server: legacy-crm-01

Lista de Verificación de Rollback

  • Base de datos restaurada a estado pre-migración
  • Todos los servicios corriendo normalmente
  • Flujos de trabajo críticos funcionales
  • Integraciones operacionales
  • Sin pérdida de datos confirmada
  • Métricas de rendimiento normales
  • Usuarios pueden acceder al sistema
  • Equipo de soporte informado
  • Reporte de incidente iniciado

## Validación Post-Migración

### Lista de Verificación de Validación

```markdown
# LISTA DE VERIFICACIÓN DE VALIDACIÓN POST-MIGRACIÓN

## Validación de Datos (Día 1)
- [ ] Conteos de registros coinciden (100% precisión)
- [ ] Transformaciones de datos correctas (validación de muestra)
- [ ] Integridad referencial mantenida (cero huérfanos)
- [ ] Reglas de calidad de datos pasan (cero violaciones)
- [ ] Datos históricos accesibles
- [ ] Sin registros duplicados
- [ ] Todos los campos obligatorios poblados

## Validación Funcional (Día 1-3)
- [ ] Journeys críticos de usuario funcionales (100%)
- [ ] Todos los flujos de trabajo de negocio operacionales
- [ ] Autenticación de usuario funcionando
- [ ] Autorización/permisos correctos
- [ ] Funcionalidad de búsqueda operacional
- [ ] Reportes precisos
- [ ] Adjuntos de documentos/archivos accesibles

## Validación de Integración (Día 1-7)
- [ ] Todas las 12 integraciones funcionales
- [ ] Sincronización de datos funcionando
- [ ] Endpoints API respondiendo
- [ ] Manejo de errores apropiado
- [ ] Rendimiento aceptable
- [ ] Alertas de monitoreo configuradas

## Validación de Rendimiento (Día 1-14)
- [ ] Tiempos de carga de página cumplen SLA (< 2s)
- [ ] Tiempos de respuesta de búsqueda aceptables (< 1s)
- [ ] Generación de reportes dentro de límites (< 5s)
- [ ] Capacidad de usuarios concurrentes confirmada (10K usuarios)
- [ ] Rendimiento de consultas de BD optimizado
- [ ] Sin fugas de memoria detectadas

## Validación de Seguridad (Día 1-7)
- [ ] Autenticación funcionando
- [ ] Reglas de autorización aplicadas
- [ ] Encriptación de datos verificada
- [ ] Logs de auditoría operacionales
- [ ] Requisitos de cumplimiento cumplidos
- [ ] Escaneo de seguridad completado (cero problemas críticos)

## Aceptación de Usuario (Día 7-14)
- [ ] Sign-off de UAT recibido (todas las unidades de negocio)
- [ ] Capacitación completada
- [ ] Documentación de usuario actualizada
- [ ] Equipo de soporte capacitado
- [ ] Feedback recopilado y abordado

## Validación Operacional (Día 1-30)
- [ ] Backups operacionales
- [ ] Monitoreo configurado
- [ ] Alertas funcionales
- [ ] Respuesta a incidentes probada
- [ ] Líneas base de rendimiento establecidas
- [ ] Planificación de capacidad actualizada

## Desactivación (Día 30-60)
- [ ] Acceso a sistema legacy revocado
- [ ] Archivo de datos final completado
- [ ] Hardware desactivado
- [ ] Licencias terminadas
- [ ] Documentación archivada
- [ ] Retrospectiva de proyecto completada

Conclusión

Las pruebas de migración exitosas requieren planificación meticulosa, documentación completa y validación rigurosa en cada etapa. Siguiendo los marcos, plantillas y mejores prácticas descritos en esta guía, las organizaciones pueden minimizar los riesgos de migración, asegurar la integridad de datos y lograr transiciones de sistemas fluidas.

Recuerda que las pruebas de migración no se tratan solo de mover datos—se tratan de asegurar la continuidad del negocio, mantener la calidad de datos, validar funcionalidad y establecer la base para el éxito futuro.