Чтобы проверить соответствие между унаследованным процессом партийной обработки на COBOL и его заменой на Java, ручной тестировщик должен запустить обе системы с идентичными входными наборами данных и провести сопоставление по полям. Методология включает стратифицированную выборку записей — приоритизируя транзакции высокой ценности, граничные даты (например, 29 февраля, переходы годов) и крайние случаи с плавающей запятой — а не исчерпывающее сравнение. Тестировщики должны экспортировать выходные данные в нейтральные форматы (например, CSV) и использовать инструменты сравнения, одновременно вручную проверяя критически важные финансовые поля на расхождения в округлении. Особое внимание должно быть уделено преобразованиям Юлианских дат и поведению арифметики с упакованными десятичными значениями (COMP-3) по сравнению с реализациями с плавающей запятой по стандарту IEEE 754. В заключение, проверка контрольных сумм и хеш-сравнения всех выходных файлов служат как предварительное тестирование перед началом детального анализа полей.
В мультинациональном банке мне было поручено валидировать миграцию ночной задачи накопления процентов с IBM Mainframe системы COBOL на Spring Boot микросервис, работающий на Linux. Унаследованная система обрабатывала миллиарды транзакций на протяжении десятилетий, используя арифметику упакованных десятичных значений COMP-3 и форматы Юлианской даты (YYDDD), в то время как новое Java приложение использовало BigDecimal и стандартные Григорианские календари. Основной проблемой было обеспечение битового совпадения выходных данных; даже одноцентное расхождение по миллионам счетов могло бы стать критическим финансовым дефектом, а тонкие различия в режимах округления или расчетах високосных годов могли бы привести к значительным отклонениям.
Одним из рассмотренных решений было полное сравнение файлов всех выходных записей. Этот подход предлагал исчерпывающее покрытие и абсолютную уверенность в том, что каждый байт совпадает. Однако плюсы были перевешены серьезными минусами: набор данных содержал более пятидесяти миллионов записей, что делало ручное сравнение физически невозможным в рамках ночного пакетного окна, а огромное количество шума от ожидаемых различий метаданных (например, временных меток) замаскировало бы реальные недостатки данных.
Другим вариантом была простая случайная выборка фиксированного процента записей, скажем, один процент. Хотя это обеспечивало статистически значимый обзор и было быстро выполнено, минусы были неприемлемыми для финансового аудита: случайная выборка могла легко упустить высокоэффективные выбросы, такие как тип счета с уникальными правилами округления или транзакции, происходящие 29 февраля 2024 года, которые исторически вызывали ошибки в логике преобразования Юлианских дней.
Выбранным решением была стратегия стратифицированной выборки в сочетании с автоматизированными скриптами сравнения для ручной валидации. Мы классифицировали записи по уровням риска: Уровень 1 включал все счета с балансом, превышающим один миллион долларов, и все транзакции на граничных датах (конец месяца, конец года, високосные дни), в то время как Уровень 2 охватывал случайные выборки из различных типов продуктов. Этот подход был выбран, потому что он уравновешивал необходимость абсолютной уверенности по высоко рискованным транзакциям с практическими ограничениями времени ручного тестирования.
Для Уровня 1 мы выполнили 100% ручное сопоставление на уровне полей с использованием Beyond Compare и пользовательских Python скриптов для выделения дельт, в то время как для Уровня 2 мы проверяли агрегатные контрольные суммы и случайно проверяли отдельные поля. В результате было обнаружено критическое несоответствие, где COBOL сокращал промежуточные результаты вычислений до пяти десятичных знаков, в то время как деление по умолчанию BigDecimal в Java сохраняло масштаб непредсказуемо, вызывая расхождение в $0.01 по счетам с высокой процентной ставкой. После обнаружения мы скорректировали режим округления Java на HALF_UP с явным масштабом, достигнув идеального соответствия.
Как вы обнаруживаете повреждение кодировки при проверке файлов фиксированной ширины, мигрированных с EBCDIC на ASCII?
Многие тестировщики визуально проверяют данные в текстовых редакторах, упуская из виду, что COBOL мейнфреймы часто используют кодовую страницу EBCDIC CP037, в то время как системы Java используют UTF-8. Специальные символы, такие как знаки валюты (€, £) или акцентированные буквы в именах клиентов, могут отображаться неправильно. Для проверки необходимо открыть файлы в шестнадцатеричном редакторе, чтобы сравнить побитовые представления, убедившись, что завершающие пробелы в COBOL (часто шестнадцатеричное 40) не перепутаны с нулевыми терминаторами в Java (шестнадцатеричное 00), и что упакованные десятичные поля (COMP-3) правильно распакованы без повреждения знакового бита.
Почему могут две математически эквивалентные операции давать разные результаты в COBOL и Java, даже когда обе используют "десятичные" типы?
Кандидаты часто предполагают, что BigDecimal гарантирует идентичное поведение упаковочного десятичного типа COBOL. Тем не менее, COBOL выполняет арифметику с основанием 10 с фиксированной точностью, определяемой PIC клаузой (например, PIC 9(9)V99), обрезая промежуточные результаты на каждом этапе операции в соответствии с бизнес-правилами. BigDecimal в Java по умолчанию сохраняет произвольную точность, если вы явно не устанавливаете MathContext и RoundingMode. Решением является воспроизводство логики обрезания COBOL путем связывания операций с явными вызовами setScale() и сопоставления режима округления унаследованной системы (часто HALF_UP или HALF_EVEN) на каждом промежуточном шаге, а не только на конечном результате.
Как вы проверяете временную точность, когда унаследованная система игнорирует переход на летнее время (DST), в то время как новое приложение Java использует UTC или местное время с учетом DST?
Это часто упускается из виду, потому что тестировщики сравнивают временные метки поверхностно. Если унаследованная работа COBOL работает по EST (восточное стандартное время) круглый год, в то время как сервис Java использует America/New_York (который переходит на EDT), транзакции, происходящие между 2:00 AM и 3:00 AM во второе воскресенье марта, будут иметь смещение в один час. Чтобы решить эту проблему, тестировщики должны конвертировать обе временные метки в канонический формат (например, UTC миллисекунды эпохи) во время ручной проверки, убедиться, что параметры обрезки пакета "конец дня" (часто "23:59:59") интерпретируются последовательно, и гарантировать, что логика граничных дат (например, "последний рабочий день месяца") не смещается из-за отсутствующего часа весной или лишнего часа осенью.