Edge Hunt
Корнер редко выглядит необычно по частям. Обычно ломается пересечение обычного
состояния, обычного действия и неучтённого порядка событий. Не пытаться просто
«подумать внимательнее»: построить пространство задачи и системно столкнуть его
измерения.
Сначала убедиться, что задача и масштаб уже выбраны. Этот скилл укрепляет края
решения, но не доказывает, что выбрано правильное решение. Если направление ещё
обсуждается, вернуться к
или
.
1. Зафиксировать нормальный контракт
Одной короткой цепочкой записать:
исходное состояние → действие → видимый результат → что обязано сохраниться
Последний элемент обязателен. Неявные гарантии вроде «закрыл временную панель —
вернулся к прежней работе» чаще выпадают из постановки, чем основной результат.
Не изобретать контракт только по тикету. Проверить релевантные код, тесты,
документацию, историю решений и соседние сценарии. Разделить:
- подтверждённое текущее поведение;
- выбранное новое поведение;
- предположение без источника;
- вопрос, требующий продуктового решения.
2. Выделить измерения именно этой задачи
Выбрать только те оси, которые физически участвуют в изменении:
- состояние до действия;
- способ входа и вариант действия;
- порядок, повтор, отмена и прерывание;
- форма, объём и свежесть данных;
- роль, права и смена доступа;
- этап жизненного цикла: первый случай, следующий, спустя время, после restart,
update, миграции или отзыва доступа;
- время ответа, retry и поздний результат;
- устройство, вкладка, процесс или внешняя интеграция;
- параллельное действие другого участника или воркера.
Для каждой выбранной оси назвать 2–5 различающихся классов, а не перечислять
все возможные значения. Отметить невозможные сочетания и основание, которое их
исключает.
3. Породить корнеры
Применить к выбранным осям пять операций:
- Пересечение. Скрестить пары условий. Для потери данных, прав, платежей,
синхронизации и необратимых действий проверить также тройки.
- Перестановка. Поменять порядок связанных действий; повторить действие;
вставить отмену, возврат, перезапуск или продолжение после паузы.
- Нарушение инварианта. Попытаться потерять то, что должно сохраняться:
основную работу, идентичность, выбор, данные, права или возможность вернуться.
- Разрез сбоя. Поместить ошибку до эффекта, во время частичного эффекта и
после эффекта, но до подтверждения пользователю.
- Сдвиг по жизненному циклу. Повторить сценарий не только сразу, но для
второго и последующего объекта, после истечения времени, перезапуска,
обновления, миграции или отзыва внешнего права.
Не останавливаться на названиях вроде «ошибка сети». Описывать полную ситуацию:
что уже произошло, что не произошло, что видит человек и что случится при
повторе.
Подробный механизм и примеры —
references/generation-methods.md
.
4. Отобрать важное
Оставить обычно 5–10 сценариев. Поднимать выше случаи, где:
- несколько обычных условий создают неожиданный результат;
- возможны тихая потеря данных, нарушение прав или необратимое действие;
- граница проходит между двумя компонентами, устройствами или моментами времени;
- поведение существует в продукте, но не записано в постановке;
- проверка способна опровергнуть решение, а не только подтвердить реализацию.
Не добавлять корнер только потому, что он теоретически возможен. Назвать связь с
реальным состоянием, веткой кода, контрактом, прошлым багом или внешней
гарантией. Невозможные, уже закрытые нижним слоем и не относящиеся к изменению
случаи отбросить.
5. Превратить находку в решение
Для каждого оставшегося корнера определить один статус:
- поддержать сейчас — без него задача не выполняет свой контракт;
- сохранить прежнее — новое решение не должно менять существующий сценарий;
- оставить за границей — случай реален, но его цена не входит в эту задачу;
- нужен новый факт — сначала наблюдение, лог, решение человека или живая
проверка.
Не перекладывать на пользователя обратимые локальные решения. Рекомендовать
поведение по существующему контракту; спрашивать только там, где выбор меняет
продукт, данные, права или скоуп.
6. Проверить, а не только перечислить
Если доступны код или живой продукт, безопасно проверить 1–3 самых рискованных
сценария до реализации либо включить их в план проверки. Предпочитать пробу,
которая может опровергнуть гипотезу: воспроизведение, state-machine test,
property-based test, fault injection или минимальную последовательность событий.
Выбрать сигнал, который физически наблюдает сломанный слой: визуальное поведение
проверять в живом интерфейсе, сохранность данных — повторным чтением из
хранилища, права — запросом с нужной ролью, восстановление — реальным restart.
Зелёная проверка не считается подтверждением, если она не могла увидеть дефект.
Не выдавать придуманный сценарий за найденный дефект. Отдельно помечать:
подтверждено кодом, воспроизведено, следует из контракта или остаётся гипотезой.
Результат
Начать с самого опасного пропуска. Для каждого корнера кратко дать:
| Ситуация | Ожидаемое поведение | Почему её легко пропустить | Статус | Проверка |
|---|
В конце назвать, какие измерения проверены, какие сознательно исключены и какое
одно неизвестное сильнее всего ограничивает уверенность. Не превращать ответ в
ритуальный чеклист и не расширять задачу молча.