Test manualeIng. QA Manuale

Durante la verifica di una migrazione di un lavoro batch da **COBOL** a **Java** per l'elaborazione di transazioni finanziarie ad alto volume, quale metodologia di testing manuale granulare applicheresti per garantire un output identico bit per bit tra sistemi legacy e moderni, rilevando discrepanze sottili di arrotondamento in virgola mobile e anomalie nella gestione degli anni bisestili delle **date giuliane**?

Supera i colloqui con l'assistente IA Hintsage

Risposta alla domanda

Per verificare la parità tra un processo batch legacy in COBOL e il suo sostituto in Java, un tester manuale deve eseguire entrambi i sistemi contro dataset di input identici e effettuare una riconciliazione campo per campo. La metodologia prevede un campionamento stratificato dei record, dando priorità alle transazioni ad alto valore, alle date di confine (ad esempio, 29 febbraio, cambi di anno) e ai casi limite in virgola mobile, piuttosto che a un confronto esaustivo. I tester dovrebbero esportare gli output in formati neutri (come CSV) e utilizzare strumenti di confronto mentre ispezionano manualmente campi finanziari critici per eventuali discrepanze di arrotondamento. Sono necessarie particolari attenzioni alle conversioni di date giuliane e al comportamento aritmetico in formato decimale compresso (COMP-3) rispetto alle implementazioni in virgola mobile IEEE 754. Infine, la convalida dei checksum e i confronti hash di interi file di output servono come test iniziale prima che inizi l'analisi dettagliata dei campi.

Situazione reale

Presso una banca multinazionale, mi è stato assegnato il compito di convalidare la migrazione di un lavoro batch notturno per l'accumulo degli interessi da un sistema COBOL su mainframe IBM a un microservizio Spring Boot in esecuzione su Linux. Il sistema legacy aveva elaborato miliardi di transazioni per decenni utilizzando aritmetica decimale compressa COMP-3 e formati di date giuliane (YYDDD), mentre la nuova applicazione Java utilizzava BigDecimal e calendari gregoriani standard. Il problema principale era garantire un output identico bit per bit; anche una singola discrepanza di un centesimo su milioni di conti costituirebbe un difetto finanziario critico, e differenze sottili nei modi di arrotondamento o nei calcoli sugli anni bisestili potrebbero portare a variazioni materiali.

Una soluzione considerata è stata un confronto forzato di file tra tutti i record di output. Questo approccio offriva una copertura esaustiva e certezza assoluta che ogni byte fosse corrispondente. Tuttavia, i pro sono stati superati da gravi controindicazioni: il dataset conteneva oltre cinquanta milioni di record, rendendo impossibile il confronto manuale all'interno della finestra overnight, e l'enorme volume di rumore proveniente da differenze di metadata attese (come i timestamp) avrebbe coperto i reali difetti dei dati.

Un'altra opzione era un semplice campionamento casuale di una percentuale fissa di record, ad esempio l'uno percento. Mentre questo forniva una panoramica statisticamente significativa ed era veloce da eseguire, i contro erano inaccettabili per la verifica finanziaria: il campionamento casuale potrebbe facilmente trascurare casi outlier ad alto impatto, come un tipo di conto specifico con regole di arrotondamento uniche o transazioni verificatisi il 29 febbraio 2024, che storicamente hanno attivato bug nella logica di conversione delle date giuliane.

La soluzione scelta è stata una strategia di campionamento stratificato combinata con script di differenziazione automatizzati per la convalida manuale. Abbiamo classificato i record per livelli di rischio: il Livello 1 includeva tutti i conti con saldi superiori a un milione di dollari e tutte le transazioni su date di confine (fine mese, fine anno, giorni bisestili), mentre il Livello 2 copriva campioni casuali da diversi tipi di prodotto. Questo approccio è stato selezionato perché bilanciava la necessità di una certezza assoluta nelle transazioni ad alto rischio con le pratiche limitazioni di tempo per il testing manuale.

Per il Livello 1, abbiamo effettuato una riconciliazione manuale al 100% a livello di campo utilizzando Beyond Compare e script personalizzati in Python per evidenziare le differenze, mentre per il Livello 2 abbiamo verificato i checksum aggregati e controllato singoli campi. Il risultato è stata la scoperta di un difetto critico dove COBOL troncava i risultati delle calcolazioni intermedie a cinque decimali, mentre la divisione predefinita di BigDecimal di Java manteneva la scala in modo imprevedibile, causando una variazione di $0.01 sugli account ad alto interesse. Una volta identificato, abbiamo regolato la modalità di arrotondamento di Java a HALF_UP con scala esplicita, raggiungendo una parità perfetta.

Cosa spesso i candidati trascurano

Come rilevi la corruzione dell'encoding quando convalidi file a larghezza fissa migrati da EBCDIC a ASCII?

Molti tester ispezionano visivamente i dati in editor di testo, trascurando che i mainframe COBOL spesso utilizzano la pagina di codice EBCDIC CP037, mentre i sistemi Java utilizzano UTF-8. Caratteri speciali come simboli di valuta (€ , £) o lettere accentate nei nomi dei clienti potrebbero essere mappati in modo errato. Per verificare, è necessario aprire i file in un editor esadecimale per confrontare le rappresentazioni a livello di byte, assicurandosi che gli spazi finali in COBOL (spesso esadecimale 40) non siano confusi con terminatori null in Java (esadecimale 00), e che i campi decimali compressi (COMP-3) siano estratti correttamente senza corruzione del bit di segno.

Perché due calcoli matematicamente equivalenti potrebbero dare risultati diversi in COBOL rispetto a Java, anche quando entrambi utilizzano tipi "decimali"?

I candidati spesso presumono che BigDecimal garantisca un comportamento identico a quello del decimale compresso di COBOL. Tuttavia, COBOL esegue operazioni aritmetiche in base 10 con precisione fissa dettata dalla clausola PIC (ad esempio, PIC 9(9)V99), troncando i risultati intermedi ad ogni passo operativo secondo le normative aziendali. BigDecimal di Java, per impostazione predefinita, mantiene una precisione arbitraria a meno che non impostiate esplicitamente un MathContext e un RoundingMode. La soluzione consiste nel replicare la logica di troncamento di COBOL concatenando le operazioni con chiamate esplicite a setScale() e abbinando la modalità di arrotondamento legacy (spesso HALF_UP o HALF_EVEN) ad ogni passo intermedio, non solo al risultato finale.

Come verifichi l'accuratezza temporale quando il sistema legacy ignora l'ora legale (DST) mentre la nuova applicazione Java utilizza UTC o ora locale con consapevolezza del DST?

Spesso questo viene trascurato perché i tester confrontano superficialmente i timestamp. Se il lavoro legacy COBOL è eseguito in EST (Eastern Standard Time) tutto l'anno mentre il servizio Java utilizza America/New_York (che passa a EDT), le transazioni che avvengono tra le 2:00 AM e le 3:00 AM la seconda domenica di marzo avranno uno spostamento di un'ora. Per risolvere questo, i tester devono convertire entrambi i timestamp in un formato canonico (ad esempio, millisecondi epoch UTC) durante la convalida manuale, verificare che i parametri di chiusura batch di "fine giornata" (spesso "23:59:59") siano interpretati in modo coerente e assicurarsi che la logica di confine delle date (ad esempio, "ultimo giorno lavorativo del mese") non cambi a causa dell'ora mancante in primavera o dell'ora extra in autunno.