Чек-лист тестирования форм: 30+ кейсов, которые забывают
Форма — это место, где данные пользователя встречаются с вашей системой. И именно здесь живёт большинство «скучных» багов: обрезанные пробелы, потерянный ввод, отправка дважды. Хорошая новость — формы тестируются по чек-листу, и этот чек-лист переиспользуется на любой форме: логин, оплата, профиль, заявка.
Ниже — сгруппированный разбор + готовый плоский чек-лист, который можно сохранить и прогонять.
1. Текстовые поля
- Пробелы: ведущие/хвостовые trim’ятся (или явно нет — но осознанно); строка только из пробелов не проходит как «заполнено».
- Max length: ввод обрезается/блокируется на лимите; что в БД — не длиннее; счётчик символов честный.
- Unicode и emoji: имя
Ø, иероглифы, 😀 — сохраняются и отображаются без????и краша. - RTL (арабский/иврит), смешанный LTR+RTL текст — не ломает раскладку.
- Вставка из буфера: длинный текст, текст с переносами/таб/невидимыми символами, форматированный текст.
- Регистр и нормализация: email/логин — приводятся к нижнему регистру там, где надо; Unicode-нормализация (é как один символ vs два).
2. Валидация
- Required: пустое обязательное поле ловится; сообщение понятное и рядом с полем.
- Момент валидации: inline (на blur/ввод) vs on-submit — консистентно; не раздражает валидацией на каждый символ.
- Сообщения об ошибке: что не так И как исправить, без «Error 0x0» и без вины пользователя.
- Граничные значения: min/max длины и значения ровно на границе и ±1.
- Зависимые поля: «другое» включает текстовое поле; страна меняет формат индекса/телефона.
- Повторная валидация на сервере: клиентскую проверку можно обойти — сервер обязан проверять то же самое (OWASP Input Validation).
3. Числа и деньги
- Разделители: тысячные/десятичные по локали (1,000.50 vs 1 000,50); запятая vs точка.
- Отрицательные, ноль, ведущие нули (007), знак +, экспонента (1e9).
- Деньги: округление, копейки/центы, отсутствие float-ошибок (0.1+0.2), валюта и её формат.
- Переполнение: очень большое число, max int, длинная дробь — не падает и не теряет точность.
- Нечисловой ввод в числовое поле: буквы, пробелы, спецсимволы — отклоняются понятно.
4. Спец-поля: email, телефон, дата, пароль
- Email:
user+tag@, поддомены, длинные TLD, unicode-домены; не слишком строгий regex (валидные адреса не должны отвергаться). - Телефон: международный формат E.164, +, скобки/дефисы/пробелы, разные длины по странам.
- Дата: формат по локали, граничные (29 фев, 31 апреля), будущее/прошлое там где нельзя, таймзоны — см. отдельный чек-лист по датам.
- Пароль: правила сложности понятны заранее; вставка разрешена (запрет paste — антипаттерн); показать/скрыть; очень длинный пароль; пробелы по краям.
5. Маски и автозаполнение
- Маска ввода (карта/телефон/дата) не мешает вставке и не ломает курсор при правке в середине.
- Браузерный/системный autofill заполняет поля корректно и триггерит валидацию (частый баг — autofill, а кнопка всё ещё disabled).
- Менеджер паролей подставляет логин/пароль; поля помечены правильными
autocomplete-атрибутами.
6. Сабмит и идемпотентность
- Двойной клик / быстрый повторный submit → запрос уходит один раз (кнопка дизейблится, спиннер). Не создаётся два заказа.
- Enter в поле отправляет форму ожидаемо (или нет, если это textarea).
- Долгий ответ: видимое состояние загрузки, нельзя жать повторно.
- Идемпотентность на сервере: повтор того же сабмита (ретрай сети) не задваивает запись.
7. Сеть и состояния
- Обрыв сети в момент отправки: понятная ошибка, введённое НЕ потеряно, можно повторить.
- Таймаут и медленная сеть: форма не «висит» молча.
- Кнопка «Назад» браузера и refresh: предупреждение о потере данных / черновик сохранён.
- Повторная отправка после ошибки — без задвоения (см. идемпотентность).
- Сессия истекла к моменту сабмита: понятный сценарий релогина без потери введённого.
8. Безопасность
- Спецсимволы и инъекции:
' OR 1=1,<script>, шаблоны${}/{{}}— экранируются, не исполняются. - HTML/markdown в полях не рендерится как разметка там, где не должен.
- Загрузка файлов (если есть): тип/размер/имя — отдельная большая тема.
- Чувствительные поля не логируются и не кэшируются (пароли, карты).
9. Доступность ошибок
- При ошибке фокус переводится на первое невалидное поле; ошибки связаны с полем (
aria-describedby). - Ошибка не передаётся только цветом — есть текст/иконка (WCAG Error Identification 3.3.1).
- Screen reader зачитывает сообщение об ошибке (
aria-live/role=alert). - Поля имеют
<label>; placeholder не заменяет лейбл. - Навигация и сабмит с клавиатуры; видимый фокус.
Готовый чек-лист (сохранить)
- Пробелы trim’ятся; строка из пробелов ≠ заполнено.
- Max length соблюдается в UI и в БД; счётчик честный.
- Unicode/emoji/RTL сохраняются и отображаются корректно.
- Вставка из буфера (длинный/форматированный/с невидимыми символами) обработана.
- Required ловится; сообщение понятное и рядом с полем.
- Валидация консистентна по моменту (inline vs submit), не раздражает.
- Сообщения объясняют как исправить, без кодов и обвинений.
- Границы min/max длины и значения (на границе и ±1).
- Зависимые/условные поля работают.
- Серверная валидация дублирует клиентскую.
- Числа: разделители по локали, отрицательные, ноль, переполнение.
- Деньги: округление, без float-ошибок, валюта и формат.
- Email не отвергает валидные адреса (+tag, поддомены, unicode).
- Телефон: международные форматы, E.164.
- Дата: граничные, локаль, таймзоны.
- Пароль: paste разрешён, show/hide, правила понятны, длинный ок.
- Маски не ломают вставку и правку в середине.
- Autofill заполняет и триггерит валидацию (кнопка не остаётся disabled).
- Двойной submit/Enter → один запрос; кнопка дизейблится.
- Сервер идемпотентен к повтору сабмита.
- Обрыв сети: ошибка понятна, ввод не потерян, повтор без задвоения.
- Back/refresh: предупреждение/черновик.
- Истёкшая сессия: релогин без потери данных.
- Инъекции/спецсимволы экранируются, не исполняются.
- HTML в полях не рендерится как разметка.
- Пароли/карты не логируются и не кэшируются.
- Фокус на первое невалидное поле при ошибке.
- Ошибка не только цветом; есть текст/иконка.
- Screen reader озвучивает ошибки; есть label, не только placeholder.
- Клавиатурная навигация и видимый фокус.
Мини-шаблон тест-кейса для поля
Для каждого поля прогоняйте: пусто → пробелы → минимум → максимум → за пределом → валидное → невалидный формат → спецсимволы → вставка → autofill. Это покрывает 90% багов поля за один проход.
Итог
Формы кажутся простыми, но именно в них копятся незаметные баги, которые бьют по конверсии и данным. Системный чек-лист по категориям (поля → валидация → сабмит → сеть → безопасность → доступность) превращает «вроде потыкал» в воспроизводимое покрытие. Сохраните и прогоняйте на каждой форме.