Слепые зоны в техническом задании: как вскрыть неучтенные сценарии в разработке ПО для бизнеса?
Если вы когда-нибудь запускали или заказывали программный продукт, то наверняка проходили через один и тот же сценарий. Сначала все участники проекта собираются и в деталях описывают, как будет работать будущая система: пользователь авторизуется, выбирает товар, нажимает кнопку оплаты, деньги списываются, заказ улетает на склад. Разработчик кивает, заказчик довольно выдыхает, все расходятся с чувством выполненного долга.
А через пару месяцев, ближе к запуску, система вдруг начинает вести себя неожиданно: кто-то загрузил в карточку товара фотографию размером с небольшой фильм, из-за чего страница каталога открывается полторы минуты, кто-то ввёл в поле «Имя» три тысячи символов, и вёрстка личного кабинета поехала.
Когда вы идёте к команде разработки с вопросом, как такое вообще возможно, вам показывают техническое задание – и там действительно ничего про это не сказано. Не потому, что кто-то схалявил, а потому, что на старте обсуждали исключительно счастливый путь, без отклонений.
Вот эти разрывы между описанным поведением системы и реальным миром мы называем слепыми зонами. Они есть в любом проекте, даже если над ним работали очень внимательные люди, потому что на этапе обсуждения будущего продукта почти невозможно держать в голове все способы, которыми живой пользователь или среда могут сломать стройную логику.
К счастью, эту проблему можно серьёзно смягчить, если перед стартом разработки провести ревизию требований особым образом – без погружения в код, но с прицелом на поиск того, о чём все забыли спросить, с помощью методики «черный ящик».
Далее мы вместе разберем наиболее популярные слепые зоны, а также узнаем как применять метод черного ящика в любом ИТ-проекте!
А что произойдет если действие не выполнится?
У технического задания есть одна интересная особенность: оно почти всегда пишется в уверенности, что всё пойдёт по плану. Мы описываем, как пользователь нажимает кнопку, как система обрабатывает запрос, как на экране появляется результат.
Это естественный ход мысли – никто не начинает проект со словами «давайте придумаем, что у нас сломается», но именно эта привычка оставляет за кадром огромный набор ситуаций, в которых операция по каким-то причинам не доходит до финала.
Возьмём классический пример – оплату заказа. В стандартном техническом задании сценарий выглядит примерно так: клиент нажимает «Оплатить», платёжный шлюз проводит транзакцию, деньги списываются, система создаёт заказ и отправляет подтверждение.
На демонстрации в тестовой среде это работает безупречно, все довольно кивают, идём дальше. Но в реальной жизни между нажатием кнопки и зачислением денег может случиться небольшой хаос, и вот лишь несколько его сценариев:
- Платёжный шлюз зависает на несколько секунд и возвращает ошибку, из которой неясно, успела ли транзакция обработаться.
- Банк одобряет платёж, но в момент передачи ответа обратно в вашу систему обрывается связь, и заказ остаётся в подвешенном состоянии – деньги у клиента списаны, а склад об этом не знает.
- Клиент просто закрывает вкладку браузера, пока крутится индикатор загрузки, и теперь он не понимает, платить повторно или ждать, когда с ним свяжутся.
- Сам платёж проходит успешно, но письмо с подтверждением не отправляется, потому что почтовый сервис в этот момент не отвечает, и клиент остаётся в полной тишине после списания денег.
Каждый из этих пунктов находится за пределами «счастливого пути», и каждый способен испортить пользовательский опыт ровно в тот момент, когда человек уже расстался с деньгами – то есть в самой чувствительной точке взаимодействия с вашим бизнесом.
Если такие сценарии не обсудить заранее, разработчик примет решение сам. Скорее всего, он поступит аккуратно с технической точки зрения: настроит автоматическую отмену заказа через десять минут неопределённого статуса, и код будет выглядеть прилично.
Только вот если вы торгуете билетами на событие, которое начнётся через полчаса, эти десять минут означают, что место уже продано другому, а ваш клиент сидит с непонятным списанием в банковской выписке и зреющим раздражением.
Методика «черный ящик» предлагает простой подход: для каждой важной операции задать вопрос «а что, если не получилось?» и пройтись по всем стадиям процесса. Не нужно придумывать техническое решение – это как раз задача команды разработки. От вас требуется описать желаемое поведение системы на языке бизнеса: как долго мы готовы ждать ответа от внешнего сервиса, что видит пользователь в это время, кто в вашей компании получает уведомление о зависшей операции, через какое окно мы принудительно закрываем неопределённый статус и что делаем с деньгами?
Чем конкретнее будут ответы на эти вопросы, тем меньше импровизаций возникнет на этапе написания кода.
Есть ещё один полезный приём – мысленно добавлять частицу «не» к каждому шагу сценария и смотреть, разваливается ли от этого общая картина. Пользователь ввёл данные, но не нажал кнопку, нажал, но шлюз не ответил, шлюз ответил, но код ответа не совпадает ни с одним из описанных в документации.
Внутри каждого такого «не» прячется требование, которое пока отсутствует в техническом задании, и чем раньше вы его оттуда достанете, тем меньше неожиданностей вылезет на финише.
И главное, о чём стоит помнить: разработчик не будет специально разбираться, какое поведение системы выгоднее для вашего клиентского опыта. У него другая работа – сделать так, чтобы код не падал. Поэтому всё, что касается бизнес-логики в нештатных ситуациях, должно исходить от вас. В конце концов, именно вам потом объяснять пользователю, почему деньги списались, а заказ так и не приехал.
Пограничные состояния и лимиты
Есть одна закономерность, которую редко проговаривают вслух при старте проекта, но с которой сталкиваются почти все: система, спроектированная на десять пользователей, и та же самая система при десяти тысячах – это два совершенно разных продукта.
Беда в том, что техническое задание почти всегда пишется под первый сценарий, потому что на старте никого нет, нагрузка нулевая, а все тесты проходят на горстке записей в базе данных, а потом проект выходит в реальную жизнь, и начинается отрезвление.
Пограничные состояния – это не только про высокие нагрузки, хотя и про них тоже. Это про любую ситуацию, где количество, объём или частота чего-либо упираются в невидимый потолок, о котором никто не подумал заранее.
Представьте себе поиск по каталогу товаров, в техническом задании написано: «Пользователь вводит запрос, система выдаёт подходящие результаты». Всё логично, никто не спорит, но за этим «выдаёт» скрывается как минимум несколько развилок, каждая из которых способна превратить удобный поиск в источник головной боли:
- По запросу нашлось двести тысяч товаров. Система честно пытается показать их все, страница грузится двадцать секунд, пользователь уходит к конкуренту, даже не дождавшись результата.
- По запросу не нашлось вообще ничего. Система показывает пустой серый экран, потому что сценарий нулевой выдачи никто не прорабатывал, и вместо того чтобы предложить похожие товары или изменить формулировку запроса, мы просто ставим пользователя в тупик.
- Пользователь не ввёл ни одной буквы и нажал кнопку поиска. Что должна сделать система: показать всё подряд, выдать ошибку или мягко попросить ввести хоть что-то? В спецификации этого нет, разработчик делает как проще, и в результате мы получаем либо десятисекундную загрузку всего каталога, либо раздражённого клиента.
Другой пример – загрузка файлов: вы даёте пользователям возможность загружать фотографии к отзывам или изображения в карточку товара. В требованиях указано: «Поддерживаются форматы JPEG и PNG». Этого достаточно, чтобы разработчик сделал работающую функцию. Но достаточно ли этого для вашего бизнеса?
Допустим, контент-менеджер загружает фотографию с камеры в формате TIFF весом под сорок мегабайт, потому что ему так удобно и он не обязан разбираться в тонкостях веб-оптимизации. Система честно пытается обработать этот файл, сервер тратит на это память и процессорное время, и вот уже страница каталога, на которой висит этот товар, открывается у всех посетителей в три раза медленнее обычного.
Ещё один частый гость – пакетная обработка данных. В техническом задании часто пишут: «Система должна позволять выгружать отчёт за выбранный период». В тестовой среде период в две недели отрабатывает за пару секунд. А через полгода ваш бухгалтер запрашивает отчёт за три года, нажимает кнопку и уходит пить чай, пока сервер задыхается под тяжестью запроса.
Через минуту запрос падает по таймауту, бухгалтер пробует снова, серверу становится ещё хуже, и в итоге никто не может работать. И снова никто не виноват: требование вроде бы сформулировано, просто никто не уточнил границы.
Методика «черный ящик» предлагает для каждого такого места задать четыре простых вопроса, которые можно занести в таблицу прямо во время обсуждения требований:
Самое коварное свойство пограничных состояний в том, что они редко проявляют себя на этапе разработки. У разработчика локально всё летает, потому что в его базе три тестовых товара и один заказ.
Проблемы начинаются позже, когда система попадает в реальную среду с реальными данными и реальными людьми, которые загружают фотографии слона в разрешении, избыточном для печати рекламного щита. И в этот момент выясняется, что «поиск работает» и «поиск работает быстро» – это два разных требования, и второе в техническом задании почему-то отсутствовало.
Исправлять такие вещи на этапе запуска всегда дороже, чем предусмотреть на старте. Причём речь не идёт о том, чтобы покрыть вообще все мыслимые сценарии – это невозможно, да и не нужно, достаточно пройтись по тем узким местам, где объём данных или частота обращений гарантированно вырастут со временем, и хотя бы в общих чертах описать, как система должна вести себя на границах.
Пользователь-разрушитель
Когда мы проектируем программный продукт, то невольно держим в голове образ идеального пользователя. Этот человек читает подсказки на экране, вводит данные в правильном формате, не нажимает кнопки бездумно и вообще ведёт себя предсказуемо.
Наверное, где-то такие пользователи существуют, но в реальной жизни за компьютер садятся люди с совершенно разными привычками, уровнем терпения и технической подготовки. И некоторые из них способны устроить системе проверку на прочность, даже не подозревая об этом.
Назовём их «пользователями-разрушителями»: они не хакеры, не злоумышленники и не конкуренты, это обычные люди, которые просто делают что-то не так, как мы ожидали, и в этом нет никакого злого умысла. Проблема в том, что техническое задание редко учитывает их манеру поведения, а значит и система оказывается к ней не готова.
Первый – «Человек, который очень спешит»: он не читает текст на кнопках, дважды нажимает «Оформить заказ», потому что система не отреагировала мгновенно, и создаёт два одинаковых заказа вместо одного, закрывает страницу оплаты до того, как платёж обработался, а потом открывает её снова и пробует другой картой – просто потому, что не увидел сообщения «Платёж обрабатывается, пожалуйста, подождите».
Он пролистывает форму до конца, заполняет только обязательные поля, а все необязательные пропускает, и потом удивляется, почему курьер не может дозвониться, хотя номер телефона был как раз в необязательном поле.
Второй – «Человек, который не доверяет интерфейсу». Он копирует данные из других документов и вставляет их в поля формы вместе с невидимыми пробелами, переносами строк и иногда кусками форматирования.
В поле «Имя» оказывается «Анна\r\n», и потом система не может найти её в базе при повторном входе. Он вводит номер телефона то с восьмёркой, то с плюсом, то с дефисами, то вообще без них – и каждый раз система реагирует по-разному, потому что никто не описал единый сценарий обработки.
Третий – «Человек, который экспериментирует». Он загружает в поле для аватара фотографию паспорта, пытается вставить в текстовое поле ссылку на сторонний сайт, пишет отзыв длиной в несколько страниц, потому что ему есть что сказать или пробует ввести в поле «Год рождения» значение «Александр», просто чтобы посмотреть, что будет.
Формально все эти действия не запрещены спецификацией, потому что в спецификации не было слов «запретить загрузку фотографий паспорта в поле аватара». А раз не запрещено – значит, система должна это как-то обработать.
Если не обсудить таких персонажей заранее, разработчик создаст продукт, который отлично держится на демонстрации и немедленно ломается в первые же сутки реальной эксплуатации. Причём ломается не фатально, а мелкими, раздражающими способами: дублируются заказы, теряются клиенты, подвисает интерфейс.
Методика «Черный ящик» предлагает простой приём: перед утверждением технического задания собрать небольшой список персонажей и прогнать через них каждый ключевой сценарий. Персонажей не нужно придумывать с нуля, достаточно опереться на три проверенные роли:
- «Спешащий» – делает всё максимально быстро, не читает подсказки, нажимает кнопки по несколько раз, закрывает страницы до завершения операций.
- «Копирующий» – вставляет данные из буфера обмена, таскает за собой скрытые символы, смешивает форматы ввода.
- «Любопытный» – пробует нестандартные сценарии, загружает не те файлы, вводит не те данные, проверяет систему на прочность просто из интереса.
Для каждого из них задаются одни и те же вопросы: что он сломает на этом шаге, как система должна отреагировать и что мы покажем пользователю, чтобы он понял, что пошло не так. Ответы на эти вопросы превращаются в конкретные требования, которые затем попадают в техническое задание.
Удивительным образом такая нехитрая процедура снимает огромный пласт будущих проблем. Разработчик получает чёткое описание того, как обрабатывать краевые случаи, а не додумывает их сам в три часа ночи перед сдачей этапа.
Служба поддержки получает систему, которая дружелюбно объясняет пользователю ошибку, а не выдаёт красную строку с техническим кодом, а пользователи, даже те, что очень спешат или очень любопытны, остаются с ощущением, что система на их стороне, а не воюет с ними.
Как применять черный ящик на практике?
После всего сказанного выше может сложиться впечатление, что мы предлагаем перед каждым проектом проводить многодневное расследование с допросами, блок-схемами и рисованием злых персонажей на доске.
На самом деле методика «Черный ящик» устроена гораздо проще и не требует от заказчика ни технических знаний, ни специальной подготовки, её можно провести за одну-две встречи с командой разработки, если правильно организовать разговор.
Нам понадобится одна конкретная функция будущей системы: одна сквозная операция, которую пользователь выполняет от начала и до конца. Например, регистрация нового пользователя, оформление заказа, поиск по каталогу, загрузка документа в личный кабинет. Возьмите ту функцию, которая для вашего бизнеса наиболее критична, и начните с неё, остальные потом можно будет проработать по тому же шаблону.
Дальше мы рисуем простую таблицу из трёх колонок. Никаких специальных программ не нужно, подойдёт обычная электронная таблица или даже лист бумаги, если встреча проходит очно. Колонки называются так:
- Счастливый путь
Сюда мы записываем идеальный сценарий – тот самый, который обычно уже описан в техническом задании или в черновиках требований. Эту колонку важно зафиксировать первой, потому что она служит точкой отсчёта: мы не спорим с ней и не подвергаем её сомнению, мы просто переносим её на бумагу или в таблицу в том виде, в каком она существует на текущий момент.
- Серые зоны
Мы берём каждый шаг из «Счастливого пути» и по очереди спрашиваем: а что, если на этом месте что-то пошло не так? Не фатально, не катастрофично, а просто немного не по плану: пользователь ввёл не тот формат телефона, платёж завис на несколько секунд. Всё это – «серые зоны», то есть ситуации, которые не ломают систему целиком, но требуют от неё осмысленной реакции.
- Красный код
Сюда попадают сценарии, на которые у нас пока нет ответа. Например, что происходит с личными данными, если пользователь начал регистрацию, но не закончил её? Хранятся ли они вообще? Если да, то как долго и кто имеет к ним доступ? Мы не даём готовых ответов прямо на встрече, но чётко фиксируем вопросы и назначаем ответственного за их проработку с указанием срока.
Одна из главных опасностей этого метода – уйти в бесконечное обсуждение гипотетических ситуаций, которые никогда не случатся. Чтобы этого избежать, полезно придерживаться нескольких простых правил.
Выделите фиксированное время. На разбор одной функции достаточно часа или полутора. Если за это время вы не успели закрыть все вопросы, назначьте ещё одну встречу, но не пытайтесь втиснуть всё в одну бесконечную сессию – внимание рассеивается, и качество обсуждения падает.
Пригласите нужных людей. На встрече обязательно должны быть тот, кто отвечает за бизнес-логику со стороны заказчика, и тот, кто будет принимать технические решения со стороны разработчика. Без первого вы рискуете получить систему, которая технически безупречна, но бесполезна для реальных клиентов. Без второго – список требований, который невозможно реализовать в рамках разумного бюджета.
Не оценивайте стоимость на лету. Когда звучит вопрос из серии «а что, если платёжный шлюз не ответит», разработчик может немедленно начать прикидывать, сколько человеко-часов уйдёт на обработку этого сценария. Попросите его пока этого не делать, сначала соберите все вопросы, потом приоритизируйте их, и только после этого переходите к оценке.
Фиксируйте всё. Каждый ответ, каждый новый вопрос, каждое принятое решение должны остаться в таблице. После встречи эта таблица отправляется обеим сторонам и становится приложением к техническому заданию. Когда через месяц кто-то спросит: «Почему мы решили, что письмо должно уходить трижды с интервалом в пятнадцать минут?» – достаточно открыть таблицу и найти тот самый пункт в колонке «Серые зоны».
После нескольких таких встреч у вас на руках появляется документ, который закрывает не только «счастливый путь», но и все обнаруженные отклонения от него. Разработчик больше не вынужден додумывать поведение системы в нештатных ситуациях – у него есть чёткие указания от заказчика. Вы, со своей стороны, получаете уверенность в том, что будущий продукт не развалится при первом же столкновении с реальным пользователем.
Разработка ПО от 66 Бит
Всего за 10 минут вы узнали о том, как контролировать узкие слепые зоны в техническом задании на разработку ПО для бизнеса. Сейчас самое время задуматься о выборе надежного подрядчика, поэтому мы рады предложить свою кандидатуру!
Опытные специалисты 66 Бит проведут глубокий аудит ваших процессов и систем, займутся их поддержкой и ростом, а также разработают новое ПО для производительности вашего бизнеса. Подробнее читайте на нашем сайте!