В системе Vest выполнение тестов построено вокруг детерминированного порядка, в котором каждая проверка входит в общий поток выполнения и обрабатывается строго последовательно в рамках одного запуска. Это поведение определяет предсказуемость результатов, возможность раннего прерывания и контроль над зависимыми проверками.
Каждый набор правил в Vest представляет собой последовательность тестов, которые выполняются в порядке их объявления. Такая модель отличается от параллельных валидаторов тем, что результат каждого шага может повлиять на дальнейший ход выполнения.
Ключевая особенность заключается в том, что выполнение не перескакивает между тестами произвольно: система проходит по цепочке сверху вниз, фиксируя состояние каждого узла проверки.
Базовая структура выполнения:
Синхронные тесты являются фундаментом последовательного исполнения. Они выполняются мгновенно и не требуют ожидания внешних ресурсов. Внутри Vest они образуют линейный поток, в котором каждый следующий тест получает доступ к уже вычисленным результатам предыдущих шагов.
Пример логики:
suite("user", () => {
test("username", "Имя обязательно", () => {
enforce(data.username).isNotBlank();
});
test("age", "Возраст должен быть числом", () => {
enforce(data.age).isNumber();
});
test("age", "Возраст должен быть > 18", () => {
enforce(data.age).greaterThan(18);
});
});
В этом примере важен не только набор правил, но и их порядок. Каждое последующее правило выполняется после предыдущего без перепрыгивания или переупорядочивания.
Одним из ключевых аспектов линейного выполнения является поведение при возникновении ошибок. Vest может продолжать выполнение или остановиться в зависимости от конфигурации.
При стандартной стратегии выполнение выглядит так:
Однако при включении режима раннего выхода цепочка обрывается на первом критическом нарушении. Это изменяет поведение последовательности, превращая её в условный поток.
Последовательное выполнение особенно важно в сценариях, где один тест зависит от результата другого. Например, проверка формата данных должна происходить до проверки бизнес-логики.
test("email", "Некорректный email", () => {
enforce(data.email).matches(emailPattern);
});
test("email", "Email уже используется", async () => {
await checkEmailExists(data.email);
});
Здесь второй тест имеет смысл только если первый прошёл успешно. Последовательность обеспечивает корректность такой логики без необходимости ручного управления зависимостями.
Асинхронные тесты в Vest не нарушают порядок выполнения. Они встраиваются в общий поток и приостанавливают дальнейшее выполнение до завершения промиса.
Последовательность приобретает вид:
test("username", "Проверка доступности", async () => {
await api.checkUsername(data.username);
});
test("username", "Дополнительная проверка", () => {
enforce(data.username.length).greaterThan(3);
});
Асинхронная точка становится естественным барьером в потоке исполнения, не нарушая линейную структуру.
Внутри одного набора можно выделять логические группы, но даже при группировке порядок остаётся глобальным внутри всего suite. Группы не создают параллельных потоков — они лишь структурируют последовательность.
Особенность заключается в том, что вложенность не влияет на порядок выполнения:
Последовательное выполнение в Vest тесно связано с механизмами условного пропуска. Тест может быть пропущен, если предыдущие условия не выполнены.
Типичный сценарий:
Если базовая проверка не пройдена, последующие тесты могут быть исключены из выполнения для оптимизации.
test("password", "Слишком короткий пароль", () => {
enforce(data.password.length).greaterThan(6);
});
test("password", "Сложность пароля", () => {
enforce(data.password).matches(strongPasswordPattern);
});
При провале первого теста второй может быть логически неактуален, хотя формально остаётся в последовательности.
Последовательная модель позволяет системе оптимизировать выполнение за счёт:
Внутренний механизм анализа потока определяет, какие тесты могут быть пропущены без потери целостности результата.
В сложных схемах с множеством полей порядок выполнения становится критическим фактором предсказуемости.
Пример:
test("profile.name", "Имя обязательно", () => {});
test("profile.email", "Email обязателен", () => {});
test("profile.email", "Email формат", () => {});
test("profile.age", "Возраст обязателен", () => {});
test("profile.age", "Возраст корректен", () => {});
Последовательность здесь определяет не только порядок ошибок, но и момент их обнаружения. Это влияет на пользовательскую обратную связь и структуру итогового результата.
Важное свойство системы заключается в том, что порядок тестов фиксируется в момент создания набора. Динамическое изменение структуры во время выполнения не влияет на уже сформированную последовательность.
Это обеспечивает:
Любая логика, зависящая от динамического изменения порядка, выносится за пределы тестового потока.
Каждая ошибка в последовательной системе фиксируется в контексте конкретного шага. Это создаёт линейную карту нарушений, где каждая ошибка связана с конкретной точкой выполнения.
Такая модель позволяет:
Последовательное выполнение формирует не просто набор результатов, а структурированную траекторию проверки данных.