Автоматизация проверок

Использование Intl API в JavaScript требует строгого контроля корректности локализации, поскольку результат форматирования зависит от множества параметров: языка, региона, календаря, часового пояса, политик округления и системных настроек окружения. Автоматизация проверок позволяет гарантировать стабильность поведения форматеров и предотвращает регрессии при изменении кода, обновлении браузеров или библиотек.


Принципы тестирования Intl API

Поведение объектов Intl.NumberFormat, Intl.DateTimeFormat, Intl.Collator, Intl.ListFormat и других не является полностью детерминированным без фиксации входных параметров. Поэтому тестирование строится вокруг следующих принципов:

  • фиксация locale и параметров форматирования
  • контроль среды выполнения (таймзона, календарь, часовой пояс)
  • сравнение результатов через предсказуемые строки
  • изоляция от системных локалей CI-среды

Ключевое требование — устранение вариативности окружения.


Тестирование форматирования чисел

Intl.NumberFormat используется для локализованного отображения чисел, валют и процентов. Основная задача автоматизации — контроль стабильности форматирования.

const formatter = new Intl.NumberFormat('de-DE', {
  style: 'decimal',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

formatter.format(1234567.89);

В тестах фиксируется ожидаемое значение:

test('number formatting in de-DE', () => {
  const formatter = new Intl.NumberFormat('de-DE', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  });

  expect(formatter.format(1234567.89)).toBe('1.234.567,89');
});

Контроль валют

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

Автоматизация проверяет:

  • корректность символа валюты
  • позицию символа (до/после числа)
  • правила округления

Тестирование дат и времени

Intl.DateTimeFormat зависит от локали, календаря и временной зоны. Основная проблема автоматизации — нестабильность системного времени и окружения CI.

const formatter = new Intl.DateTimeFormat('en-GB', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});

Для детерминированных тестов фиксируется Date:

test('date formatting en-GB', () => {
  const formatter = new Intl.DateTimeFormat('en-GB', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });

  const date = new Date('2025-01-15T00:00:00Z');

  expect(formatter.format(date)).toBe('15/01/2025');
});

Контроль часовых поясов

Особую сложность создаёт параметр timeZone. Без его фиксации результат зависит от окружения.

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'UTC',
  hour: '2-digit',
  minute: '2-digit'
});

Автоматизированные проверки фиксируют:

  • смещение времени
  • переходы между датами
  • поведение при границах суток

Тестирование сортировки строк

Intl.Collator отвечает за корректную сортировку с учётом локали.

const collator = new Intl.Collator('sv-SE');

['ä', 'z', 'a'].sort(collator.compare);

Автоматизация проверяет:

  • порядок символов с диакритикой
  • устойчивость к регистру
  • соответствие языковым правилам
test('sorting sv-SE locale', () => {
  const collator = new Intl.Collator('sv-SE');

  const result = ['ä', 'z', 'a'].sort(collator.compare);

  expect(result).toEqual(['a', 'z', 'ä']);
});

Тестирование списков

Intl.ListFormat используется для формирования читаемых списков.

const formatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});

Автоматизация проверяет:

  • корректные разделители
  • наличие союзов
  • поведение при 1, 2, n элементах
test('list formatting en', () => {
  const formatter = new Intl.ListFormat('en', {
    style: 'long',
    type: 'conjunction'
  });

  expect(formatter.format(['apples', 'oranges', 'bananas']))
    .toBe('apples, oranges, and bananas');
});

Изоляция окружения в CI

Среда непрерывной интеграции часто имеет непредсказуемые локали. Для устранения вариативности применяются:

  • явное указание locale
  • фиксация timeZone
  • использование polyfill-реализаций ICU

Пример конфигурации тестового окружения:

process.env.TZ = 'UTC';

Дополнительно тесты избегают:

  • зависимостей от системного языка
  • нефиксированных дат
  • автоматических локалей Node.js

Snapshot-тестирование Intl API

Snapshot-подход используется для фиксации строк форматирования.

const formatter = new Intl.NumberFormat('fr-FR', {
  style: 'currency',
  currency: 'EUR'
});

formatter.format(1999.99);

Snapshot сохраняет результат:

"1 999,99 €"

При изменении ICU-данных или браузерной реализации изменения фиксируются автоматически через дифф.


Проверка обратной совместимости

Обновления Node.js и браузеров могут менять поведение Intl. Автоматизация направлена на выявление:

  • изменения форматирования валют
  • обновления правил округления
  • изменения локальных разделителей
  • корректировки календарных систем

Регрессионные тесты сравнивают текущие результаты с эталонными.


Тестирование граничных случаев

Особое внимание уделяется крайним значениям:

  • очень большие числа
  • отрицательные значения валют
  • високосные даты
  • переходы через границу DST
new Intl.DateTimeFormat('en-US').format(new Date('2024-03-10T02:30:00'));

Такие сценарии выявляют ошибки временных зон и календарных преобразований.


Моки и стабилизация Intl

В некоторых сценариях требуется замена реализации Intl на предсказуемую версию.

Подходы:

  • подмена глобального Intl
  • использование фиксированных ICU данных
  • внедрение polyfill-библиотек

Пример изоляции:

global.Intl = require('intl');

Стратегии обеспечения детерминизма

Стабильность тестов достигается через:

  • фиксацию входных параметров форматеров
  • контроль среды выполнения
  • устранение зависимости от локали системы
  • явное указание всех опций Intl
  • использование эталонных значений

Автоматическая проверка локалей

При поддержке множества языков применяется массовое тестирование:

  • прогон одинаковых данных через набор локалей
  • сравнение длины и структуры строк
  • выявление переполнений интерфейса
const locales = ['en', 'de', 'fr', 'ja'];

locales.forEach(locale => {
  const formatter = new Intl.NumberFormat(locale);
  formatter.format(12345.67);
});

Контроль визуальной стабильности

Форматирование влияет на UI, поэтому проверяется:

  • ширина строк
  • наличие неразрывных пробелов
  • символьные различия между локалями
  • устойчивость интерфейса при смене языка

Интеграция в CI/CD пайплайны

Автоматизированные проверки Intl API включаются в pipeline:

  • запуск unit-тестов с фиксированным окружением
  • snapshot-сравнение
  • прогон матрицы локалей
  • контроль ICU-версий

Такая схема предотвращает деградацию локализации на уровне сборки.