🎯 Итерация 8: @Step
, @Scenario()
и автономные классы шагов
Цель
Выделить шаги сценария в отдельный класс, сделать их читаемыми, переиспользуемыми и автоматически выполняемыми в Allure-отчётах — без ручного вызова step(...)
и без boilerplate-кода runAllSteps()
.
Решение
1. @Step()
— помечает любой метод как шаг для Allure
@Step('Проверка email')
async checkEmail() { ... }
2. @Scenario()
— помечает класс, в котором шаги должны выполняться последовательно
@Scenario()
class AccessSteps { ... }
3. runSteps(instance, ctx)
— универсальный раннер для таких классов
await runSteps(AccessSteps, this.ctx)
Что мы сделали
- ✅ Создали
@Step()
— минимальный декларативный шаг - ✅ Добавили
@Scenario()
— метку класса для автоматического исполнения - ✅ Написали
runSteps()
— запуск шагов по порядку - ✅ Добавили поддержку
@Context()
внутри step-класса
Пример использования
@Scenario()
class AccessSteps {
@Context()
ctx!: { email?: string; token?: string; status?: number }
@Step('Проверка email')
async checkEmail() {
expect(this.ctx.email).toMatch(/@example\.com/)
}
@Step('Проверка токена')
async checkToken() {
expect(this.ctx.token).toBe(this.ctx.email + '-token')
}
}
И в тесте:
await runSteps(AccessSteps, this.ctx)
Что это даёт?
- 🧩 Выделить шаги в отдельные модули (шаги = lego-блоки сценария)
- ♻️ Использовать один и тот же набор шагов в разных сценариях и классах
- 🧠 Читаемые отчёты Allure с понятными шагами
- 🎯 Автоматическое исполнение — порядок = порядок в коде
- 🚀 Запускать шаги автоматически, без ручного вызова — даже в других раннерах
Это решение вдохновлено практиками Serenity и Playwright, но адаптировано под декларативный DSL.
Идея на будущее
Можно автоматически вызывать шаги по условию, по профилю, по пользовательской логике.
Этот фундамент пригодится нам и для более сложных кейсов: например, вложенных шагов, UI-цепочек, сценариев c branching.
🧠 Ключевая мысль
@Step
+@Scenario()
превращают набор методов в декларативный сценарий.
runSteps()
— ваш сценарный раннер.