Состояния: проверяем не только экран, но и переход
Строим последовательности create → draft → publish и проверяем инварианты отказов.
- Отличить состояние, действие и результат запроса.
- Выбрать последовательности, которые ловят нарушения переходов.
- Проверить состояние после успеха и отказа независимым наблюдением.
Карта вместо несвязанного списка
Состояние — факт о продукте, который влияет на допустимые действия. В OrbitDesk это draft и published. «Ошибка валидации» — результат операции, а не третье состояние задачи. «Пользователь вышел» — состояние сессии, которое можно учитывать отдельно. Если соединить всё в один список статусов, модель быстро станет непроверяемой. Начните с малого: существование задачи, её статус, актор и одно событие.
Создание валидной задачи переводит отсутствие объекта в draft. Успешная публикация переводит draft в published. Чтение не меняет состояние. Повторная публикация published в OD-1 даёт 409; она не создаёт копию и не возвращает объект в draft. Из этого учебного контракта нельзя выводить правила архивирования или удаления — таких событий здесь нет.
Переходы OD-1
| Откуда | Событие и условие | Ответ | Куда |
|---|---|---|---|
| Объекта нет | Создание валидных данных под сессией | 201 | draft |
| draft | Автор/editor, валидный непустой title | 200 | published |
| draft | Публикация без прав | 403 | draft |
| draft | Автор, title из пробелов | 422 | draft |
| published | Повтор publish с правами | 409 | published |
| draft/published | Разрешённое read | 200 | Без изменения |
Последовательность обнаруживает то, что отдельная кнопка не показывает
Выполните create под Анной, сохраните ID, затем read под Борисом-user. Он не должен увидеть draft. Попытка publish Бориса получает 403, после чего повторное read Анны всё ещё показывает draft. Далее Анна публикует задачу; Борис теперь читает published. Наконец, повтор publish Анны получает 409, а ID не меняется. Число задач проверяется отдельным разрешённым снимком списка или хранилища: чтение одного ID не доказывает отсутствие копии. Эта последовательность связывает приватность, переход и отсутствие побочного эффекта.
ИИ может предложить вместо этого три независимых запроса, каждый к заранее опубликованной задаче. Такой набор проверяет ответы для published, но не переход из draft и не изменение видимости. Просите помощника явно записывать начальное состояние каждой операции. Если предусловие не обеспечено, результат теста нельзя интерпретировать.
Инварианты и наблюдения
Инвариант — свойство, которое должно сохраняться через выбранные операции. В нашем кейсе автор не меняется при публикации; отказ не меняет статус; чтение не меняет объект; успешный publish не создаёт вторую задачу. Проверяйте сохранённые поля повторным чтением от разрешённого актора, а не только уведомлением интерфейса. Для отсутствия копии нужен отдельный полный список или разрешённый снимок хранилища; без него эту часть не отмечайте пройденной. По возможности запишите ID запроса и сравните серверное представление до и после.
Не путайте бизнес-идемпотентность с HTTP-методом. OD-1 намеренно отклоняет повтор публикации с 409. Можно проектировать API иначе, например возвращать текущий published при повторе, но это другое согласованное правило. ИИ не должен «исправлять» ваш оракул по общему совету из статьи.
Отдельная проверка сбоя и повторения
Поведение при потере ответа требует дополнительного контракта. Если соединение оборвалось после отправки publish, клиент не знает, произошло ли изменение. Полезный вопрос — как UI восстанавливает актуальное состояние и отличает повторное нажатие от новой операции. Пока ответа нет, не придумывайте гарантии exactly-once. В учебной практике мы проверяем последовательные ответы известного API, а сетевую неопределённость фиксируем отдельным непокрытым риском. Такой честный предел полезнее заявления «проверены все состояния».
ЗАДАЧА Построй минимальную модель переходов и последовательности проверок. КОНТЕКСТ OD-1: только draft и published, create/read/publish. ВХОДНЫЕ ДАННЫЕ Учебный продукт OrbitDesk, версия правил OD-1. Все имена и данные вымышлены. R1: title — строка от 1 до 80 кодовых точек Unicode включительно. При сохранении пробелы автоматически не удаляются. R2: description — строка от 0 до 2000 кодовых точек. Пустая строка разрешена, null не является строкой. R3: новая задача получает состояние draft и автора из серверной сессии. R4: читать draft может только автор; published виден всем вошедшим участникам той же команды. Роль editor сама по себе не открывает чужой draft. R5: опубликовать draft может автор или editor из той же команды. При публикации title.trim() не должен быть пустым. trim — поведение JavaScript String.prototype.trim; сохранённое значение не изменяется. R6: публикация переводит draft в published. Повторная публикация published отклоняется с 409, состояние не меняется. R7: в учебном API проверки публикации идут в порядке: сессия 401 → существование/команда 404 → права 403 → состояние 409 → данные 422 → успех 200. Это контракт кейса, не универсальное правило API. R8: создание (create): без сессии — 401; неверный тип или длина title/description — 422 без создания; переданные клиентом authorId, teamId или state отклоняются с 422; успех — 201 и одна новая задача draft с новым ID, автором из сессии и исходными строками без trim. Чтение (read): без сессии — 401; неизвестный объект, чужая команда или чужой draft — 404 без содержимого задачи; разрешённое чтение — 200 с объектом. R9: отказ в create/read/publish не меняет объекты; read не меняет данные. Успешный publish меняет только состояние существующей задачи, сохраняя ID, автора, title и description; дополнительная задача не создаётся. Акторы и фикстуры: Анна — user, автор t1, команда A; Борис — user, не автор t1, команда A; Вера — editor, не автор t1, команда A; Глеб — editor, команда B. Дина — editor и автор отдельной задачи t2 команды A для проверки сочетания автор-editor. Если не указано иное, t1 — draft с title="Проверить экспорт" и description="". Обозначения t1/t2 — учебные псевдонимы фактически полученных ID, а не требование к генератору ID. Перед независимым тестом фикстура восстанавливается. ОГРАНИЧЕНИЯ Не добавляй archive/delete. Отделяй состояние объекта от ошибки и сессии. Для отказов сохраняй наблюдение до/после. ОЖИДАЕМЫЙ ФОРМАТ Таблица переходов; одна сквозная последовательность с акторами; инварианты; открытые вопросы о сбоях.
Используйте разрешённый ИИ-сервис. Не отправляйте рабочие секреты и персональные данные.
Источники и проверка фактов
ISTQB — CTFL v4.0, программа и материалыРазделы анализа и проектирования тестов; курс использует собственные учебные примеры, не является подготовкой к сертификации.OWASP API 1: Broken Object Level AuthorizationПрава нужно проверять для конкретного объекта и действия на сервере; скрытая кнопка не является проверкой доступа.Авторский учебный материал · Редакция QA Orbit · версия 2026-10-28.1