Тестирование граничных значений

Граничные значения представляют собой критические точки диапазона допустимых данных, на которых поведение системы может изменяться. В контексте валидации данных именно эти точки становятся основным источником дефектов, так как ошибки чаще всего возникают не внутри диапазона, а на его границах.

Для строк это минимальная и максимальная длина. Для чисел — минимально и максимально допустимые значения. Для форматов — минимально допустимые структурные требования, например наличие символов, доменной зоны или корректного диапазона дат.

Библиотека Validator.js предоставляет набор функций, которые позволяют формализовать проверки таких границ и применять их в тестовых сценариях и прикладной валидации.


Подход к тестированию граничных значений

Методика тестирования граничных значений основывается на анализе допустимых диапазонов входных данных и проверке поведения системы в следующих точках:

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

Такой подход позволяет выявить ошибки, связанные с неправильной реализацией условий сравнения (<, <=, >, >=) и некорректной обработкой крайних случаев.

Validator.js не является тестовым фреймворком, однако его функции широко используются для реализации проверок, которые затем включаются в unit-тесты или интеграционные тестовые сценарии.


Проверка длины строк

Одной из наиболее частых задач является валидация длины строковых значений: пароли, логины, имена, описания.

В Validator.js используется функция isLength, позволяющая задать минимальные и максимальные границы:

const validator = require('validator');

validator.isLength('abc', { min: 2, max: 5 }); // true

Граничные сценарии для длины строки

Рассматриваются следующие случаи:

  • длина равна минимальному значению
  • длина на 1 меньше минимального значения
  • длина равна максимальному значению
  • длина на 1 больше максимального значения

Пример тестового набора:

const validator = require('validator');

const min = 3;
const max = 8;

const cases = [
  'ab',       // ниже минимума
  'abc',      // минимальная граница
  'abcdef',   // внутри диапазона
  'abcdefgh', // максимальная граница
  'abcdefghi' // выше максимума
];

cases.map(str => ({
  value: str,
  valid: validator.isLength(str, { min, max })
}));

Особое внимание уделяется корректной интерпретации параметров min и max, так как ошибка в знаке сравнения приводит к систематическому смещению допустимого диапазона.


Числовые диапазоны и их границы

Для числовых значений Validator.js предоставляет функции isInt и isFloat, которые позволяют задавать диапазоны:

validator.isInt('10', { min: 1, max: 100 });

Граничные точки для целых чисел

Ключевые сценарии:

  • значение равно нижней границе
  • значение меньше нижней границы на 1
  • значение равно верхней границе
  • значение больше верхней границы на 1

Пример:

const validator = require('validator');

const options = { min: 10, max: 20 };

const values = [9, 10, 15, 20, 21];

values.forEach(v => {
  console.log(v, validator.isInt(String(v), options));
});

Особенности обработки строковых чисел

Validator.js работает со строковыми входными данными, поэтому важным аспектом тестирования становится корректность преобразования:

  • ведущие нули
  • пробелы
  • отрицательные значения
  • знаки плюса
validator.isInt(' 10 '); // false
validator.isInt('10');   // true
validator.isInt('+10');  // true
validator.isInt('-10');  // true

Граничные значения в числовых проверках часто пересекаются с проблемами парсинга строк, что требует отдельного тестирования каждого варианта представления числа.


Проверка длины и структуры email

Email-валидация через isEmail не имеет явных числовых границ, однако включает структурные ограничения, которые также подлежат граничному тестированию.

validator.isEmail('test@example.com');

Граничные сценарии email

Анализируются:

  • минимальная локальная часть
  • отсутствие локальной части
  • отсутствие домена
  • минимальная доменная структура
  • наличие поддоменов

Примеры:

const validator = require('validator');

const emails = [
  'a@b.c',              // минимально допустимая структура
  '@example.com',       // отсутствие локальной части
  'test@',              // отсутствие домена
  'test@example',       // неполный домен
  'test@example.com'    // корректный случай
];

emails.map(e => ({
  value: e,
  valid: validator.isEmail(e)
}));

Граничное тестирование email направлено не на числовые пределы, а на минимальную допустимую структуру адреса.


URL и граничные случаи структуры

Функция isURL проверяет корректность URL-адресов, где также существуют структурные границы:

validator.isURL('https://example.com');

Критические границы URL

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

Пример тестирования:

const validator = require('validator');

const urls = [
  'example.com',              // без протокола
  'http://a.co',              // минимальный домен
  'https://example.com',      // корректный
  'https://example.com:8080', // с портом
  'https://'                  // неполный URL
];

urls.forEach(u => {
  console.log(u, validator.isURL(u));
});

Даты и временные границы

Validator.js содержит функцию isDate, которая проверяет корректность даты в строковом формате.

validator.isDate('2024-01-01');

Граничные сценарии дат

  • минимально допустимая дата (начало диапазона системы)
  • конец месяца
  • високосный год
  • 31 февраля как несуществующая дата
  • переходы между годами
const validator = require('validator');

const dates = [
  '2024-02-29', // високосный год
  '2023-02-29', // некорректная дата
  '2024-12-31', // конец года
  '2024-01-01', // начало года
  '2024-04-31'  // несуществующая дата
];

dates.forEach(d => {
  console.log(d, validator.isDate(d));
});

Комбинированные граничные проверки

В реальных системах данные редко проходят одну проверку. Обычно используется комбинация ограничений:

  • длина строки
  • формат (email, URL)
  • числовой диапазон
  • допустимые символы

Пример комбинированной проверки:

const validator = require('validator');

function validateUser(input) {
  return (
    validator.isLength(input.username, { min: 3, max: 12 }) &&
    validator.isAlphanumeric(input.username) &&
    validator.isEmail(input.email) &&
    validator.isInt(String(input.age), { min: 18, max: 65 })
  );
}

Граничные сценарии комбинированной валидации

  • минимально допустимый username + допустимые символы
  • возраст ровно 18 лет
  • возраст ровно 65 лет
  • email с минимальной структурой
  • username длиной 2 и 3 символа

Такие комбинации позволяют выявлять конфликты между различными правилами валидации.


Ошибки, возникающие на границах диапазонов

Граничные значения часто становятся источником следующих типов ошибок:

  • использование строгого неравенства вместо нестрогого
  • перепутанные min/max значения
  • некорректная обработка пустых строк
  • отсутствие приведения типов
  • несогласованность правил между фронтендом и бэкендом

Validator.js помогает стандартизировать проверку, однако не устраняет необходимость точного определения границ в бизнес-логике.


Стратегия построения тестов на основе Validator.js

При построении тестов выделяются следующие этапы:

  • определение допустимого диапазона входных данных
  • выбор граничных значений
  • формирование набора значений ниже, на границе и выше диапазона
  • применение функций Validator.js к каждому значению
  • фиксация ожидаемого результата для сравнения

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