Чек-лист тестирования поля поиска — это список коротких проверок, по которому тестировщик убеждается, что поиск на сайте или в приложении принимает любой ввод без сбоев, находит то, что должен, и не открывает дыр в безопасности. Ниже — готовый чек-лист по пяти группам (функциональность, граничные значения, безопасность, удобство, производительность), отдельно про оценку релевантности и небольшой пример автопроверки на Python.
Содержание
- Чек-лист, тест-кейс и баг-репорт: в чем разница
- Как составить чек-лист для поиска
- Функциональные проверки
- Граничные значения и нестандартный ввод
- Безопасность
- Удобство и доступность
- Релевантность и производительность
- Пример: автопроверка чек-листа на Python
- Если проверка не проходит: симптомы и причины
- Выводы
- Где применяется / связь с практикой
- FAQ
Чек-лист здесь — шаблон для типичного поиска по каталогу. Под конкретный продукт его дополняют требованиями: что именно ищется, по каким полям, с какими фильтрами.
Чек-лист, тест-кейс и баг-репорт: в чем разница
Эти три артефакта часто путают, хотя у них разная детализация и назначение.
| Артефакт | Что содержит | Когда уместен |
|---|---|---|
| Чек-лист | Одна строка = одна идея проверки + отметка «прошло/не прошло» | Быстрая проверка, опытный тестировщик, часто меняющийся продукт |
| Тест-кейс | Предусловия, шаги, входные данные, ожидаемый результат | Критичные сценарии, новички в команде, регресс, автоматизация |
| Баг-репорт | Шаги воспроизведения, фактический и ожидаемый результат, окружение | Когда проверка из чек-листа или тест-кейса не прошла |
Практичный компромисс — чек-лист с колонками «ввод» и «ожидаемый результат». Он почти так же короток, как обычный список, но его может выполнить человек, который не писал его сам.
Как составить чек-лист для поиска
- Соберите требования: по каким полям идет поиск (название, описание, артикул), есть ли фильтры, сортировка, автодополнение, лимит длины запроса.
- Разбейте возможный ввод на классы эквивалентности: обычное слово, несколько слов, цифры, спецсимволы, другой алфавит, пустой ввод. Из каждого класса достаточно одного-двух представителей.
- Для числовых ограничений добавьте граничные значения: если длина запроса ограничена 100 символами, проверяются 0, 1, 99, 100 и 101.
- Отдельной группой выпишите проверки безопасности и нефункциональные: удобство, скорость, поведение под нагрузкой.
- Один пункт — одна проверка. «Поиск работает» — не пункт, «по запросу
qaнаходятся оба курса с QA в названии» — пункт.
Функциональные проверки
Ввод и запуск поиска
— Поиск запускается и по кнопке, и по Enter; повторное нажатие не создает дублей запросов.
— Пробелы в начале и в конце не влияют на результат, двойной пробел внутри равен одинарному.
— Регистр не влияет: QA, qa и Qa дают одинаковую выдачу, в том числе для кириллицы.
— Запрос сохраняется в поле после перехода на страницу результатов и после «Назад» в браузере.
Качество совпадений (что из этого поддерживается, решают требования)
— Поиск по части слова и по нескольким словам в любом порядке.
— Морфология: тестирование находит «тестировщик» или нет — по спецификации.
— Опечатки и неверная раскладка (ntcn вместо тест), транслит (python / питон), синонимы.
Выдача
— Пустая выдача показывает понятное сообщение и подсказку, а не пустую страницу или ошибку 500.
— Фильтры и сортировка применяются к результатам поиска, а не ко всему каталогу, и сбрасываются предсказуемо.
— Пагинация: на второй странице нет повторов с первой, счетчик найденного совпадает с реальным числом.
— Найденное слово подсвечивается корректно, в том числе внутри длинного слова.
Граничные значения и нестандартный ввод
- Пустой запрос и запрос только из пробелов: поиск не выполняется либо показывает понятное сообщение.
- Один символ: либо ищет, либо просит ввести больше — по требованиям, но без ошибки.
- Максимальная длина: ровно лимит принимается, лимит + 1 обрезается или отклоняется. Проверять и через интерфейс, и прямым запросом к API: атрибут
maxlengthв HTML ограничивает только ввод в браузере, сервер его не видит. - Спецсимволы
% _ * ? \ " ': ищутся как обычные символы и не ломают запрос. - Эмодзи, иероглифы, арабская вязь, вставка из буфера с переносами строк.
Безопасность
Проверки этого блока выполняют только на своем стенде или с письменного разрешения владельца системы.
- SQL-инъекция. Ввод
' OR 1=1 --не должен возвращать весь каталог, а одиночная кавычка — приводить к ошибке сервера. Причина уязвимости почти всегда одна: запрос склеен строкой вместо параметров. - XSS. Строка
<script>alert(1)</script>в поле не должна выполниться на странице «По запросу … ничего не найдено». Запрос выводится экранированным, в том числе в заголовке страницы и в подсказках автодополнения. - Подстановочные символы.
%и_в SQL-операторе LIKE означают «любые символы» и «любой один символ». Если их не экранировать, запрос%вернет весь каталог. - Злоупотребление. Есть ограничение частоты запросов, а очень длинный или тяжелый запрос не подвешивает сервер.
- Сообщения об ошибках не показывают пользователю стек, SQL-текст и имена таблиц.
Прохождение этих пунктов не доказывает, что поиск защищен: это минимальный набор, а не аудит безопасности.
Удобство и доступность
- Поле заметно и находится там, где его ждут (обычно в шапке), подсказка внутри поля объясняет, что можно искать.
- Автодополнение успевает за вводом, выбор подсказки работает и мышью, и стрелками с клавиатуры.
- На телефоне открывается подходящая клавиатура, есть кнопка очистки поля.
- У поля есть доступное имя (
labelилиaria-label), а до него можно дойти клавишей Tab.
Релевантность и производительность
Функционально корректный поиск может находить не то. Релевантность оценивают двумя путями:
- асессорами — люди вручную оценивают, насколько документы в выдаче соответствуют запросу, по заранее заданной шкале;
- онлайн-метриками — доля запросов с пустой выдачей, клики по результатам, позиция первого клика, добавления в корзину после поиска.
Для производительности замеряют время ответа при обычной работе и под нагрузкой, а также число запросов от автодополнения: без задержки ввода (debounce) каждая буква отправляет отдельный запрос. Целевые цифры задаются требованиями проекта, общей нормы нет.
Пример: автопроверка чек-листа на Python
Ниже — учебный поиск по списку курсов в SQLite (есть в стандартной библиотеке Python) и прогон по чек-листу. Запрос нормализуется в Python, передается параметром, символы % и _ экранируются.
import sqlite3
TITLES = ["Python Developer", "QA Engineer", "Java QA Automation",
"Тестирование API", "100% Kotlin", "C_Sharp Basics"]
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE courses (title TEXT, title_norm TEXT)")
conn.executemany("INSERT INTO courses VALUES (?, ?)",
[(t, t.casefold()) for t in TITLES])
def search(query: str, limit: int = 20) -> list[str]:
q = " ".join(query.split()).casefold() # обрезать и схлопнуть пробелы
if not q or len(q) > 100: # пустой или слишком длинный запрос
return []
q = q.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
rows = conn.execute(
"SELECT title FROM courses WHERE title_norm LIKE ? ESCAPE '\\' "
"ORDER BY title LIMIT ?", (f"%{q}%", limit))
return [r[0] for r in rows]
CHECKS = [
("регистр", "qa", ["Java QA Automation", "QA Engineer"]),
("кириллица", "ТЕСТ", ["Тестирование API"]),
("пробелы", " python ", ["Python Developer"]),
("пустой", " ", []),
("нет совпадений", "rust", []),
("символ %", "%", ["100% Kotlin"]),
("символ _", "_", ["C_Sharp Basics"]),
("кавычка", "o'reilly", []),
("инъекция", "' OR 1=1 --", []),
("длина 101", "a" * 101, []),
]
failed = 0
for name, query, expected in CHECKS:
actual = search(query)
ok = actual == expected
failed += not ok
print(f"{'PASS' if ok else 'FAIL'} {name:<15} {actual}")
print(f"Итого: {len(CHECKS) - failed} из {len(CHECKS)}")
Все десять проверок проходят:
PASS регистр ['Java QA Automation', 'QA Engineer']
PASS кириллица ['Тестирование API']
PASS пробелы ['Python Developer']
PASS пустой []
PASS нет совпадений []
PASS символ % ['100% Kotlin']
PASS символ _ ['C_Sharp Basics']
PASS кавычка []
PASS инъекция []
PASS длина 101 []
Итого: 10 из 10
Что здесь важно. Каждая строка CHECKS — это пункт чек-листа с вводом и ожидаемым результатом. Регистр приводится через casefold() в Python, потому что встроенная функция lower() в SQLite по умолчанию меняет регистр только у латиницы: на кириллице проверка «регистр» провалилась бы. Это поведение конкретной СУБД; в PostgreSQL и MySQL регистронезависимость настраивается иначе (collation, ILIKE).
Та же проверка на уязвимом коде
Неверно — запрос склеен из строки пользователя:
import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE courses (title TEXT)")
conn.executemany("INSERT INTO courses VALUES (?)",
[("Python Developer",), ("QA Engineer",)])
def search_unsafe(query: str) -> list[str]:
sql = f"SELECT title FROM courses WHERE title LIKE '%{query}%'"
return [r[0] for r in conn.execute(sql)]
print(search_unsafe("zzz' OR 1=1 --"))
try:
print(search_unsafe("o'reilly"))
except sqlite3.OperationalError as e:
print("OperationalError:", e)
Результат: инъекция вернула весь каталог, а обычная кавычка сломала запрос.
['Python Developer', 'QA Engineer']
OperationalError: near "reilly": syntax error
Исправление — параметр ? вместо подстановки в строку, как в функции search выше. Для пользователя такая ошибка выглядит как ответ 500 на запрос с апострофом — это и ловит пункт чек-листа «кавычка».
Если проверка не проходит: симптомы и причины
| Симптом | Вероятная причина |
|---|---|
| Запрос с апострофом дает ошибку 500 | SQL склеен строкой, нет параметризации |
Запрос % или _ находит все подряд |
Не экранированы подстановочные символы LIKE |
QA находит, а ТЕСТ не находит «Тестирование» |
Регистр нормализуется только для латиницы |
| Лимит длины обходится прямым запросом | Ограничение есть только в HTML, а не на сервере |
| На второй странице повторы | Нестабильная сортировка при пагинации |
Выводы
- Чек-лист поиска удобно строить по пяти группам: функциональность, граничные значения, безопасность, удобство, производительность.
- Классы эквивалентности и граничные значения сокращают перебор: из каждого класса ввода хватает одного-двух примеров.
- Кавычка,
' OR 1=1 --,%и<script>— обязательные пункты: они быстро находят самые дорогие дефекты поиска. - Ограничения ввода проверяют и в интерфейсе, и на сервере: HTML-атрибуты легко обойти.
- Пункты чек-листа с вводом и ожидаемым результатом легко перевести в автотесты.
Где применяется / связь с практикой
Освойте тему на практике
Такой чек-лист — первое, что тестировщик пишет для новой формы: поиск, фильтр, регистрация. Дальше пункты превращаются в тест-кейсы, баг-репорты и автотесты. Этот путь от проверки руками до автоматизации разбирают на курсе «QA Engineer». Попробовать формат занятий можно на бесплатных открытых уроках.
FAQ
Нужно ли проверять поиск, если он работает на готовом движке вроде Elasticsearch?
Да: движок отвечает за индекс, но настройки анализаторов, фильтры, вывод запроса на страницу и лимиты делает команда проекта, и ошибки обычно именно там.
Сколько пунктов должно быть в чек-листе?
Фиксированной нормы нет. Ориентир — каждое требование к поиску покрыто хотя бы одной проверкой, а проверки внутри одного класса ввода не дублируют друг друга.
Можно ли проверять инъекции на чужом сайте?
Нет: без разрешения владельца это может нарушать закон и правила площадки. Для практики используют свой стенд или учебные уязвимые приложения.



