Именование тестов и suite

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

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

Характерные свойства удачного имени suite:

  • отражает предметную область (например, «Пользователь», «Адрес доставки», «Платёжные данные»)
  • не содержит технических деталей (типов полей, форматов хранения)
  • остаётся стабильным при изменении внутренних правил

Пример подхода:

suite("User registration", () => {
  test("email is valid", () => {
    // ...
  });
});

Или более предметно:

suite("Account creation form", () => {
  test("password meets security requirements", () => {
    // ...
  });
});

Важный принцип: имя suite должно оставаться корректным даже при полном изменении набора тестов внутри. Если имя описывает набор полей, а не сущность, это признак слабой декомпозиции.

Именование test: точность и атомарность смысла

test в Vest описывает конкретное ограничение. Имя теста — это фактически сообщение об ошибке, которое увидит разработчик или пользователь.

Поэтому имя должно отвечать на вопрос: «что именно не так».

Хорошие свойства имени test:

  • содержит субъект проверки (что проверяется)
  • содержит условие или ограничение
  • описывает ожидаемое поведение
  • не использует абстрактные слова вроде «валидный» без контекста

Плохие примеры

test("email", ...)
test("validation", ...)
test("check password", ...)

Проблема этих формулировок — отсутствие конкретного условия. Они не дают информации о причине ошибки.

Хорошие примеры

test("email must be a valid email address", ...)
test("password must contain at least 8 characters", ...)
test("password must include a number", ...)

Каждое имя здесь уже является самостоятельным диагностическим сообщением.

Согласование языка имен

В проектах на Vest часто возникает смешение языков: код на английском, продуктовая логика на русском, UI локализован.

Существует два устойчивых подхода:

Единый английский нейминг

Используется в международных проектах:

test("username must not contain spaces", ...)

Плюс — универсальность и предсказуемость.

Локализованные имена

Используются, когда ошибки напрямую отображаются пользователю:

test("имя пользователя не должно содержать пробелы", ...)

Минус — усложнение поддержки в многоязычных системах.

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

Именование через структуру поля

Часто тесты строятся вокруг полей формы. В этом случае важно не дублировать имя поля и правило бессмысленно.

Неудачный вариант:

test("email email validation", ...)

Корректный вариант:

test("must be a valid email address", ...)

Имя поля уже подразумевается контекстом suite, поэтому повторять его внутри test избыточно.

Если же suite общий для нескольких полей:

suite("Registration form", () => {
  test("email must be valid", ...)
  test("password must be strong", ...)
});

Именование в параметризованных тестах

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

Типичная ошибка — отсутствие различимости между кейсами:

test("invalid input", ...)

При множестве входов такие ошибки становятся неразличимыми.

Правильный подход — включать данные в имя:

test("email 'test@' should be invalid", ...)
test("email 'user@mail.com' should be valid", ...)

Это делает отчёты самодостаточными без необходимости смотреть входные данные.

Именование вложенных suite

Вложенные suite используются для группировки логики по поддоменам. Имена должны формировать читаемую иерархию.

Пример:

suite("User", () => {
  suite("Authentication", () => {
    test("password must not be empty", ...)
  });

  suite("Profile", () => {
    test("display name must not exceed 50 characters", ...)
  });
});

Хорошая практика — избегать дублирования верхнего контекста внутри вложенных имён. Например, не нужно писать:

suite("User", () => {
  suite("User authentication", ...)
});

Это создаёт избыточность при чтении дерева тестов.

Семантика негативных и позитивных проверок

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

Позитивные:

test("password must include uppercase letter", ...)

Негативные:

test("password must not contain whitespace", ...)

Смешение форм приводит к неоднозначной интерпретации. Например:

test("password contains no spaces", ...)

Такое имя не всегда однозначно воспринимается как правило или как состояние.

Консистентность формулировок

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

  • must be …
  • must contain …
  • must not …
  • is required

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

test("email is required", ...)
test("email must be valid", ...)
test("email must not contain spaces", ...)

Несогласованность:

test("email required", ...)
test("email should be valid", ...)
test("no spaces in email", ...)

Вторая форма ухудшает предсказуемость сообщений.

Именование и читаемость ошибок

В Vest имя теста часто становится текстом ошибки. Поэтому не допускаются:

  • сокращения без расшифровки
  • внутренние термины системы
  • технические обозначения (regex, schema, constraint)

Плохо:

test("email regex mismatch", ...)

Хорошо:

test("email must be a valid email address", ...)

Избыточная детализация

Слишком длинные имена ухудшают восприятие и повторяют логику:

test("email must be a valid email address according to RFC 5322 specification", ...)

Лучше:

test("email must be valid", ...)

Детали спецификации должны жить в реализации, а не в имени.

Именование в контексте бизнес-правил

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

test("user must be at least 18 years old", ...)
test("order total must be greater than zero", ...)
test("username must be unique", ...)

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

Антипаттерны именования

Распространённые ошибки:

1. Дублирование слова “test”

test("test email", ...)

2. Слишком общие имена

test("invalid", ...)

3. Описание действия вместо условия

test("check email", ...)

4. Смешение нескольких правил

test("email and password are valid", ...)

Лучше разделять:

test("email must be valid", ...)
test("password must be valid", ...)

Иерархическая выразительность

Хорошо построенные имена suite и test формируют читаемую фразу при визуализации:

User registration
  Email must be valid
  Password must contain at least 8 characters

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