Control de Calidad Manual (QA)Ingeniero de QA Manual

Si se requiere verificar la integridad transaccional de un proceso de pago distribuido de comercio electrónico que abarca **Microservicios** comunicándose a través de **Apache Kafka**, bases de datos **PostgreSQL** con cumplimiento de **ACID**, y una capa de caché **Redis**, ¿qué metodología exhaustiva de pruebas manuales aplicarías para detectar condiciones de carrera entre la reserva de inventario, autorización de pago y eventos de confirmación de pedidos cuando ocurren particiones de red o retrasos en el corredor de mensajes?

Supere entrevistas con el asistente de IA Hintsage

Respuesta a la pregunta

Historia de la pregunta

Los enfoques de pruebas manuales tradicionales evolucionaron a partir de la validación de transacciones SQL monolíticas donde una sola base de datos hacía cumplir la consistencia. Con el cambio a Microservicios y Arquitectura Basada en Eventos, la garantía de calidad ahora enfrenta el desafío de verificar patrones distribuidos de Saga donde los cambios de estado se propagan de forma asíncrona a través de los límites de servicio, requiriendo nuevas metodologías para asegurar la integridad de los datos sin bloqueos de compromiso en dos fases.

El problema

El desafío principal radica en detectar condiciones de carrera y estados de fallo parcial cuando las garantías de ACID están aisladas a las bases de datos de servicios individuales. Específicamente, verificar que las reservas de inventario en PostgreSQL, las autorizaciones de pago a través de APIs externas y las confirmaciones de pedidos a través de temas de Apache Kafka mantengan la consistencia durante particiones de red, reequilibrio de consumidores de Kafka, o fallos de invalidación de caché Redis requiere comprender los compromisos del teorema CAP y las ventanas de consistencia eventual.

La solución

Una metodología de pruebas manuales inspirada en la Ingeniería del Caos que combina manipulación de tiempo precisa con mapeo de transiciones de estado. Esto implica inyectar manualmente latencia en los grupos de consumidores de Kafka usando herramientas de Proxy, simular evacuaciones de caché Redis durante transacciones activas, y verificar que las transacciones compensatorias de Saga revirtan correctamente las operaciones cuando ocurren fallos en el flujo descendente, asegurando que el sistema mantenga la consistencia sin permitir inventario fantasma o cargos duplicados.

Situación de la vida real

Un mercado de relojes de lujo se estaba preparando para el lanzamiento de una edición limitada de 100 piezas exclusivas con una demanda concurrente anticipada de más de 10,000 usuarios. La arquitectura utilizaba microservicios de Spring Boot donde el Servicio de Inventario gestionaba el stock en PostgreSQL, el Servicio de Pago se integraba con Stripe API, y Apache Kafka facilitaba la comunicación asíncrona entre ellos. Durante la simulación previa a la producción, el equipo descubrió un fallo crítico donde dos usuarios compraron simultáneamente la última unidad disponible porque la verificación y reserva de inventario se realizaron en mensajes asíncronos separados, creando un escenario de cerebro dividido donde ambos pagos fueron capturados antes de que cualquiera de los servicios de pedido confirmara la deducción del stock.

Solución 1: Escalado horizontal de consumidores de Kafka

Este enfoque implicó aumentar las instancias de consumidores para reducir la latencia en el procesamiento de mensajes y minimizar la ventana para condiciones de carrera. La ventaja principal fue la mejora del rendimiento y la reducción de la latencia bajo carga normal. Sin embargo, esto no resolvió fundamentalmente la condición de carrera; simplemente hizo que la colisión fuera estadísticamente menos probable mientras seguía siendo posible durante el tráfico máximo o eventos de reequilibrio de consumidores.

Solución 2: Implementación de bloqueos distribuidos a través de Redis Redlock

Esta estrategia introdujo mecanismos de bloqueo atómicos donde el Servicio de Inventario adquiriría un bloqueo distribuido antes de procesar cualquier solicitud de pago. Si bien esto previno modificaciones concurrentes al mismo ítem de stock, introdujo una latencia significativa en el flujo de pago, creó un posible punto único de falla si el clúster de Redis experimentaba particiones de red, y complicó los escenarios de recuperación de fallos donde los bloqueos podrían no liberarse debido a caídas de la aplicación.

Solución 3: Inyección manual de fallos orquestada con control de particiones de Kafka

Esta metodología requería que los probadores pausaran manualmente particiones específicas de Kafka utilizando herramientas administrativas como Kafdrop mientras inyectaban latencia en la red a través de políticas de red de Docker. Esto permitió la reproducción precisa de la ventana de tiempo exacta entre la autorización de pago y el compromiso de inventario. El enfoque fue intensivo en tiempo y requería privilegios elevados para manipular políticas de red de Kubernetes, pero proporcionó reproducción determinista de condiciones de carrera y observación directa de activaciones de transacciones compensatorias de Saga.

Solución elegida y justificación

La solución 3 fue seleccionada porque solo la intervención manual determinista podría exponer la vulnerabilidad de temporización en microsegundos entre servicios. Al pausar deliberadamente el consumidor de inventario mientras permitíamos que el consumidor de pago procesara, confirmamos que el sistema carecía de un bloqueo de reserva previo al pago y que los flujos de trabajo de compensación no se activaron automáticamente cuando se detectaron conflictos de inventario.

Resultado

El equipo de desarrollo implementó un patrón de compromiso en dos fases con un estado de inventario Pendiente que reservaba stock antes del procesamiento del pago. Las pruebas manuales luego verificaron que forzar un reequilibrio de Kafka durante el pago activo activaba correctamente la compensación de Saga, liberando tanto las reservas de inventario como las retenciones de pago sin pérdida de datos. El posterior lanzamiento del producto se realizó con éxito sin informes de ventas duplicadas y todas las 100 unidades contabilizadas en el libro final.

Lo que los candidatos a menudo pasan por alto

¿Cómo verificas las propiedades de ACID cuando los Microservicios implementan Consistencia Eventual en lugar de transacciones distribuidas?

Los candidatos a menudo confunden el cumplimiento de ACID de bases de datos locales con la consistencia de sistema global. En las pruebas manuales, debes crear intencionalmente escenarios donde una transacción de PostgreSQL se confirme con éxito pero la posterior publicación de mensaje de Apache Kafka falle, lo cual se puede lograr usando particiones de red de Docker para aislar el corredor de mensajes. Verifica que el servicio implemente el Patrón de Outbox o mensajería transaccional para asegurar que los compromisos de base de datos y la publicación de eventos sigan siendo atómicos. Verifica la existencia de registros huérfanos consultando la base de datos directamente mientras bloqueas el corredor de mensajes, y luego confirmando que los mecanismos de reintento eventualmente sincronizan el estado sin intervención manual o corrupción de datos.

¿Qué distingue las pruebas de Idempotencia de las pruebas de semántica de Exactamente Una en Colas de Mensajes, y por qué es crítico para la QA manual?

Muchos probadores tratan incorrectamente estos conceptos como intercambiables. La Idempotencia asegura que procesar el mismo mensaje varias veces produzca un resultado idéntico al procesarlo una vez, lo que pruebas al reproducir manualmente un mensaje de Kafka desde Offset Explorer y verificar que no ocurra un cargo duplicado o deducción de inventario. La semántica de Exactamente Una asegura que la infraestructura misma prevenga la entrega duplicada, lo que validas observando el comportamiento del productor transaccional de Kafka durante escenarios de falla del corredor. La QA manual debe verificar ambas dimensiones: que la aplicación maneje duplicados de manera adecuada a través de la lógica idempotente, y que los filtros de desduplicación basados en UUID funcionen correctamente cuando el corredor redelivra mensajes legítimamente debido a tiempos de reconocimiento.

¿Cómo validar las Transacciones Compensatorias dentro de un patrón de Saga sin arriesgar la integridad de los datos financieros de producción?

Esto requiere construir entornos de prueba aislados que reflejen los Esquemas de producción y contratos de API pero utilicen credenciales de sandbox para proveedores de pago. Inicia manualmente secuencias de fallos terminando los contenedores de Docker inmediatamente después del paso de autorización de pago pero antes de la confirmación del servicio de inventario. Verifica que el flujo de trabajo de compensación emita correctamente reembolsos y libere bloqueos distribuidos de Redis. Los candidatos a menudo pasan por alto verificar que el mecanismo de compensación en sí pueda fallar; debes probar bloqueando el camino de compensación, como simular una interrupción de red durante la fase de reversión, y asegurarte de que el sistema entre en un estado de alarma claramente definido de Compensación Fallida con alertas de monitoreo apropiadas en lugar de un estado inconsistente indefinido que podría llevar a discrepancias financieras.