Les approches traditionnelles de test manuel ont évolué à partir de la validation des transactions SQL monolithiques où une seule base de données garantissait la cohérence. Avec le passage aux Microservices et à l'Architecture Orientée Événements, l'assurance qualité fait maintenant face au défi de vérifier les motifs Saga distribués où les changements d'état se propagent de manière asynchrone à travers les frontières de service, nécessitant de nouvelles méthodologies pour garantir l'intégrité des données sans verrous de validation à deux phases.
Le défi central réside dans la détection des conditions de concurrence et des états d'échec partiels lorsque les garanties ACID sont isolées aux bases de données de service individuelles. En particulier, vérifier que les réservations d'inventaire dans PostgreSQL, les autorisations de paiement via des API externes et les confirmations de commande à travers des sujets Apache Kafka maintiennent la cohérence pendant les partitions réseau, le rééquilibrage des consommateurs Kafka, ou les échecs d'invalidation du cache Redis exige une compréhension des compromis du théorème CAP et des fenêtres de cohérence éventuelle.
Une méthodologie exhaustive de test manuel inspirée du Chaos Engineering qui combine la manipulation précise du temps avec la cartographie des transitions d'état. Cela implique d'injecter manuellement de la latence dans les groupes de consommateurs Kafka en utilisant des outils de Proxy, de simuler des évictions de cache Redis pendant des transactions actives, et de vérifier que les transactions compensatoires de la Saga annulent correctement les opérations lorsque des échecs en aval se produisent, garantissant que le système maintienne la cohérence sans permettre d'inventaire fantôme ou de frais en double.
Un marché de montres de luxe se préparait à un lancement en édition limitée de 100 pièces exclusives avec une demande concurrente anticipée de plus de 10 000 utilisateurs. L'architecture utilisait des microservices Spring Boot où le Service d'Inventaire gérait le stock dans PostgreSQL, le Service de Paiement s'intégrait avec l'API Stripe, et Apache Kafka facilitait la communication asynchrone entre eux. Lors d'une simulation en pré-production, l'équipe a découvert une faille critique où deux utilisateurs ont simultanément acheté la dernière unité disponible parce que la vérification et la réservation de l'inventaire se produisaient dans des messages asynchrones séparés, créant un scénario de cerveau partagé où les deux paiements étaient capturés avant que l'un ou l'autre service de commande ne confirme la déduction de stock.
Solution 1 : Scalabilité horizontale des consommateurs Kafka
Cette approche a impliqué l'augmentation des instances de consommateurs pour réduire le retard de traitement des messages et minimiser la fenêtre pour les conditions de concurrence. L'avantage principal était une augmentation du débit et une réduction de la latence sous une charge normale. Cependant, cela n'a pas fondamentalement résolu la condition de concurrence ; cela a simplement rendu la collision statistiquement moins probable tout en restant possible pendant le trafic de pointe ou les événements de rééquilibrage des consommateurs.
Solution 2 : Mise en œuvre de verrous distribués via Redis Redlock
Cette stratégie a introduit des mécanismes de verrouillage atomique où le Service d'Inventaire acquérait un verrou distribué avant de traiter toute demande de paiement. Bien que cela ait empêché les modifications concurrentes sur le même article de stock, cela a introduit une latence significative dans le flux de paiement, créé un point de défaillance potentiel si le cluster Redis subissait des partitions réseau, et compliqué les scénarios de récupération de défaillance où les verrous pourraient ne pas être libérés en raison de plantages d'application.
Solution 3 : Injection manuelle de défaillances orchestrées avec le contrôle de partition Kafka
Cette méthodologie nécessitait que les testeurs mettent manuellement en pause des partitions Kafka spécifiques à l'aide d'outils administratifs comme Kafdrop tout en injectant de la latence réseau via des politiques réseau Docker. Cela permettait de reproduire avec précision la fenêtre de timing exacte entre l'autorisation de paiement et l'engagement d'inventaire. L'approche était chronophage et nécessitait des privilèges élevés pour manipuler les politiques réseau Kubernetes, mais elle fournissait une reproduction déterministe des conditions de concurrence et une observation directe des déclencheurs de transactions compensatoires de la Saga.
Solution choisie et justification
La solution 3 a été choisie car seule une intervention manuelle déterministe pouvait exposer la vulnérabilité de timing en microsecondes entre les services. En mettant délibérément en pause le consommateur d'inventaire tout en permettant au consommateur de paiement de traiter, nous avons confirmé que le système manquait d'un verrou de réservation de pré-paiement et que les flux de travaux de compensation échouaient à se déclencher automatiquement lorsque des conflits d'inventaire étaient détectés.
Résultat
L'équipe de développement a mis en œuvre un motif de validation à deux phases avec un statut d'inventaire En Attente qui réservait du stock avant le traitement du paiement. Les tests manuels ont ensuite vérifié que forcer un rééquilibrage Kafka pendant le paiement actif déclenchait correctement la compensation de la Saga, libérant à la fois les réservations d'inventaire et les blocs de paiement sans perte de données. Le lancement subséquent du produit s'est déroulé avec succès sans vente en double signalée et toutes les 100 unités comptabilisées dans le registre final.
Comment vérifiez-vous les propriétés ACID lorsque les Microservices mettent en œuvre la Cohérence Éventuelle plutôt que des transactions distribuées ?
Les candidats confondent souvent la conformité ACID de la base de données locale avec la cohérence du système global. Dans les tests manuels, vous devez délibérément concevoir des scénarios où une transaction PostgreSQL est validée avec succès mais la publication subséquente de message Apache Kafka échoue, ce qui peut être réalisé en utilisant des partitions réseau Docker pour isoler le courtier de messages. Vérifiez que le service met en œuvre le Modèle Outbox ou le messagerie transactionnelle pour garantir que les validations de base de données et la publication des événements restent atomiques. Vérifiez l'existence de données orphelines en interrogeant directement la base de données tout en bloquant le courtier de messages, puis confirmez que les mécanismes de réessai synchronisent finalement l'état sans intervention manuelle ou corruption des données.
Qu'est-ce qui distingue le test de l'Idempotence du test des sémantiques Exactly-Once dans les Files de Messages, et pourquoi est-ce crucial pour l'QA manuelle ?
De nombreux testeurs traitent incorrectement ces concepts comme étant interchangeables. L'Idempotence garantit que le traitement du même message plusieurs fois produit un résultat identique à celui de sa seule exécution, ce que vous testez en répétant manuellement un message Kafka depuis Offset Explorer et en vérifiant qu'aucun frais ou déduction d'inventaire en double ne se produit. Les sémantiques Exactly-Once garantissent que l'infrastructure elle-même empêche la livraison en double, ce que vous validez en observant le comportement du producteur transactionnel Kafka lors des scénarios de basculement du courtier. L'QA manuelle doit vérifier les deux dimensions : que l'application gère les doublons de manière cohérente grâce à une logique idempotente, et que les filtres de déduplication basés sur des UUID fonctionnent correctement lorsque le courtier redélivre légitimement des messages en raison de délais de reconnaissance.
Comment validez-vous les Transactions Compensatoires au sein d'un motif Saga sans risquer l'intégrité des données financières en production ?
Cela nécessite de construire des environnements de test isolés qui reproduisent les Schémas et contrats API de production mais utilisent des identifiants de test pour les prestataires de paiement. Déclenchez manuellement des séquences d'échec en arrêtant les conteneurs Docker immédiatement après l'étape d'autorisation de paiement mais avant la confirmation du service d'inventaire. Vérifiez que le flux de travail de compensation émet correctement des remboursements et libère les verrous distribués Redis. Les candidats négligent souvent de vérifier que le mécanisme de compensation lui-même peut échouer ; vous devez tester en bloquant le chemin de compensation, par exemple, en simulant une panne réseau pendant la phase de retour en arrière, et vous assurer que le système entre dans un état d'alarme Compensation Échouée clairement défini avec des alertes de surveillance appropriées plutôt qu'un état incohérent indéfini qui pourrait conduire à des écarts financiers.