Вопросы по теории тестирования, тест-дизайну, видам и уровням тестирования, API/БД и автоматизации.
Эти понятия описывают разные уровни контроля качества, от стратегического до технического: * **Quality Assurance (QA)**: Обеспечение качества. Это превентивный процесс, направленный на улучшение процессов разработки и предотвращение появления дефектов в будущем. Фокусируется на процессах (профилактика). * **Quality Control (QC)**: Контроль качества. Это процесс анализа готового продукта для проверки соответствия требованиям. Фокусируется на продукте (выявление дефектов, верификация). * **Testing**: Тестирование. Это технический процесс выполнения программы с целью поиска дефектов (багов). Является частью QC.
Это два фундаментальных вопроса в тестировании: * **Verification (Верификация)**: «Создаем ли мы продукт правильно?». Проверка соответствия продукта спецификации, требованиям и стандартам. Проводится на всех этапах (статическое тестирование, ревью кода). * **Validation (Валидация)**: «Создаем ли мы правильный продукт?». Проверка соответствия продукта ожиданиям и потребностям реального пользователя. Проводится на готовом продукте с участием пользователей или через бизнес-сценарии.
Выделяют четыре основных уровня тестирования: 1. **Модульное (Unit) тестирование**: Тестирование отдельных минимальных компонентов кода (функций, методов, классов) в изоляции. Обычно пишется разработчиками. 2. **Интеграционное (Integration) тестирование**: Проверка взаимодействия между несколькими модулями или системами. 3. **Системное (System) тестирование**: Тестирование всей системы в сборе на соответствие исходным требованиям (функциональным и нефункциональным). 4. **Приемочное (Acceptance) тестирование**: Финальное тестирование готовой системы на соответствие бизнес-требованиям заказчика или конечного пользователя перед выпуском (UAT).
Техники тест-дизайна помогают составить оптимальный набор тест-кейсов для максимального покрытия при минимуме тестов: * **Эквивалентное разделение (Equivalence Partitioning)**: Разбиение входных данных на группы (классы), которые обрабатываются системой одинаково. * **Анализ граничных значений (Boundary Value Analysis)**: Тестирование значений на границах классов эквивалентности (граница, на один шаг влево, на один шаг вправо). * **Таблица принятия решений (Decision Table)**: Матрица условий и действий для тестирования сложной бизнес-логики. * **Диаграмма перехода состояний (State Transition)**: Моделирование состояний системы и переходов между ними под влиянием событий. * **Попарное тестирование (Pairwise Testing)**: Метод оптимизации комбинаторного тестирования, основанный на правиле, что большинство багов вызывается комбинацией максимум двух параметров.
* **Эквивалентное разделение** группирует данные. Мы берем только одного представителя из каждого класса эквивалентности (например, любое число от 18 до 65 для валидации возраста). * **Анализ граничных значений** фокусируется на стыках этих классов. Мы проверяем крайние точки класса и точки непосредственно за ними (для интервала [18, 65] граничными точками будут: 17, 18, 19 и 64, 65, 66). Опыт показывает, что программисты чаще всего ошибаются именно в граничных условиях (`<` вместо `<=`).
* **Error (Ошибка / Mistake)**: Действие человека (разработчика, аналитика), приведшее к неверному результату (например, опечатка в коде). * **Bug / Defect (Баг / Дефект)**: Непосредственная ошибка в коде программы или документе, вызванная Error. Пока код не запущен, баг является пассивным дефектом. * **Failure (Сбой)**: Отклонение работающей системы от ожидаемого поведения во время выполнения, вызванное багом в коде.
Жизненный цикл бага обычно выглядит так: 1. **New (Новый)**: Баг найден тестировщиком и зарегистрирован. 2. **Assigned (Назначен)**: Баг назначен конкретному разработчику для исправления. 3. **Active/In Progress**: Разработчик работает над исправлением. 4. **Resolved/Fixed**: Разработчик исправил баг и передал сборку на проверку. 5. **Retest/Verified**: Тестировщик проверяет исправление. Если баг не воспроизводится, статус меняется на **Closed (Закрыт)**. Если баг все еще есть — на **Reopened (Переоткрыт)**. 6. **Deferred (Отложен)** / **Rejected (Отклонен)**: Специфические статусы, когда баг признан некритичным для текущего релиза или не является багом вовсе.
* **Severity (Серьезность)**: Отражает степень влияния дефекта на работоспособность системы с технической точки зрения (Blocker, Critical, Major, Minor, Trivial). * **Priority (Приоритет)**: Отражает очередность исправления дефекта для бизнеса (High, Medium, Low). **Примеры**: * **High Severity / Low Priority**: Крэш приложения при редком сценарии использования, который выполняет 0.01% пользователей. Технически — крэш (Blocker/Critical), но бизнесу не горит (Low Priority). * **Low Severity / High Priority**: Опечатка в логотипе компании на главной странице сайта. Систему не ломает (Trivial/Minor Severity), но вредит имиджу бренда, поэтому исправить нужно немедленно (High Priority).
Регрессионное тестирование — это проверка того, что ранее написанный и протестированный функционал продолжает работать корректно после внесения изменений в код (исправления багов, добавления новых фич, обновления окружения). Его цель — убедиться, что изменения в одной части системы не вызвали «регресс» (не сломали работоспособность) в других частях.
* **Smoke (Дымовое) тестирование**: Короткий цикл тестов, проверяющий основные критически важные функции системы. Задача — убедиться, что приложение вообще запускается и основные пути работоспособны (например, логин и переход на главную). Проводится на новых сборках. * **Sanity (Санитарное) тестирование**: Узконаправленная проверка конкретной функции после ее изменения или багфикса. Задача — убедиться, что конкретная область работает стабильно перед началом полного регрессионного тестирования.
* **Ad-hoc тестирование**: Неструктурированное тестирование без предварительного тест-дизайна, планов и документации. Выполняется хаотично на основе интуиции. * **Исследовательское (Exploratory) тестирование**: Метод, совмещающий тест-дизайн, выполнение тестов и изучение продукта на лету. Тестировщик следует определенной цели (туру/хартии), но каждый следующий тест планирует на основе результатов предыдущего. Шаги документируются в виде тезисов, а не подробных тест-кейс-скриптов.
Пирамида тестирования — это концептуальная схема распределения автотестов по уровням: * **Основание (Unit-тесты)**: Их должно быть больше всего. Они быстрые в исполнении и дешевые в написании. * **Середина (Интеграционные/API тесты)**: Проверяют бизнес-логику и интеграцию сервисов. Работают медленнее модульных, но быстрее UI. * **Вершина (End-to-End / UI тесты)**: Проверяют полный путь пользователя через реальный интерфейс. Их должно быть меньше всего, так как они медленные, хрупкие и дорогие в поддержке.
Матрица прослеживаемости — это таблица, которая связывает требования к продукту с тест-кейсами и результатами их прохождения. Она гарантирует, что: 1. Все требования покрыты тестами. 2. В тест-сьюте нет лишних тестов, не привязанных к требованиям. 3. Можно легко оценить покрытие требований при подготовке к релизу.
Тестирование REST API проверяет эндпоинты без UI на корректность статус-кодов, валидность JSON схем и бизнес-логику. Основные методы: * **GET**: Запрос данных (не должен менять состояние на сервере). * **POST**: Создание нового ресурса. * **PUT**: Полная замена существующего ресурса. * **PATCH**: Частичное изменение ресурса. * **DELETE**: Удаление ресурса. Статус-коды: `2xx` (Успех), `3xx` (Редирект), `4xx` (Ошибка клиента), `5xx` (Ошибка сервера).
* **Stub (Заглушка)**: Простейшая реализация внешнего сервиса, которая возвращает жестко закодированные (hardcoded) данные на любой запрос. Используется для изоляции тестируемой системы. * **Mock (Макет)**: Более интеллектуальный объект, который настраивается на конкретные ожидания (например, должен проверить, что метод был вызван ровно 2 раза с определенными аргументами). Mocks проверяют поведение, Stubs — поставляют данные.
1. Открыть Chrome DevTools, вкладку **Performance** или **Memory**. 2. Сделать снимок кучи (Heap Snapshot) перед выполнением действий. 3. Выполнить повторяющиеся действия на странице (например, открытие/закрытие модального окна 10 раз). 4. Запустить сборщик мусора вручную (кнопка с корзиной в DevTools) и сделать второй снимок. 5. Сравнить снимки: если размер кучи или число DOM-нод выросли и не возвращаются к исходным значениям — на странице есть утечка памяти.
* **Интернационализация (I18n)**: Адаптация архитектуры ПО для поддержки разных языков и форматов без изменения кода (вынесение строк в ресурсные файлы, поддержка UTF-8, форматирование дат). * **Локализация (L10n)**: Непосредственный перевод текстов и адаптация контента под конкретный регион/культуру (перевод интерфейса, валюты, часовых поясов, культурных особенностей дизайна).
Тестирование производительности проверяет скорость работы, стабильность и масштабируемость системы. Виды: * **Load Testing (Нагрузочное)**: Проверка работы системы при ожидаемой нормальной нагрузке. * **Stress Testing (Стресс)**: Проверка поведения системы при экстремальных нагрузках и определение точки отказа. * **Soak/Stability Testing**: Проверка стабильности системы при длительной непрерывной нагрузке для поиска утечек памяти. * **Spike Testing**: Проверка реакции на резкие пиковые скачки нагрузки.
Тестирование базы данных включает проверку целостности данных, констрейнтов и триггеров. Основные сценарии: * Проверить, что данные из UI корректно записываются в таблицы БД (`SELECT`). * Проверить работу каскадного удаления (`DELETE` родительской записи удаляет дочерние). * Проверить ограничения уникальности полей (проба вставить дубликат уникального ключа). * Проверить производительность запросов при больших объемах данных с помощью индексов.
1. Перепроверить требования и спецификации (User Story, PRD). 2. Если требования описывают ожидаемое поведение однозначно — показать ссылку разработчику. 3. Если требования двусмысленны — привлечь бизнес-аналитика (BA) или продакт-менеджера (PO) для уточнения. 4. Если баг не описан в требованиях, но влияет на UX или безопасность — завести задачу на обсуждение, аргументируя важность дефекта для пользователя.
* **Чек-лист**: Простой список проверок (однострочные тезисы вроде «Проверить логин с пустым паролем»). Не содержит подробных шагов воспроизведения и ожидаемых результатов. Быстро пишется и обновляется. * **Тест-кейс**: Детализированный документ, содержащий ID, название, предусловия, шаги воспроизведения, ожидаемый результат и постусловия. Требует много времени на поддержку, но подходит для передачи джуниорам и автоматизации.
* **Черный ящик (Black Box)**: Тестировщик не знает внутреннее устройство кода. Тестирование строится исключительно на входах и выходах через интерфейс системы. * **Белый ящик (White Box)**: Тестировщик имеет полный доступ к исходному коду и логике работы программы. Тестирование проверяет пути выполнения кода, покрытия условий и циклов. * **Серый ящик (Grey Box)**: Комбинация методов. Тестировщик знает общие принципы архитектуры (структуру БД, API схемы), но само тестирование проводит на уровне интерфейсов.
Кроссбраузерное тестирование — это проверка корректности отображения и функционирования веб-приложения в различных веб-браузерах (Chrome, Safari, Firefox, Edge), их версиях и на различных движках (Blink, WebKit, Gecko) для обеспечения одинакового пользовательского опыта.
1. Зафиксировать все параметры окружения (версию ОС, браузер, разрешение экрана, сетевую скорость). 2. Попытаться найти закономерность (например, баг воспроизводится только при повторном быстром клике или при определенном состоянии кэша). 3. Изучить логи консоли браузера и логи сервера на наличие ошибок в момент воспроизведения. 4. Записать баг-репорта, прикрепив видеозапись экрана и логи, обязательно указав частоту воспроизведения (1/10) и собранные гипотезы.
Для тестирования поля ввода даты применяем техники тест-дизайна: * **Валидные значения**: Корректная дата в правильном формате (например, 25.06.2026). * **Граничные значения**: Прошлый век (01.01.1900), далекое будущее, сегодняшняя дата, високосный год (29.02.2024). * **Невалидные значения**: Несуществующие даты (31.02.2026, 32.05.2026), спецсимволы, пустой ввод, пробелы, буквы, ввод даты в некорректном формате (2026/06/25 вместо DD.MM.YYYY).
Автоматизированное тестирование — использование скриптов для выполнения проверок без участия человека. Оно окупается при длительных проектах с частыми релизами, когда стоимость написания и поддержки автотестов становится ниже затрат времени ручных тестировщиков на постоянное регрессионное тестирование.
* **Функциональное тестирование** проверяет, *что* система делает (авторизация, платежи, создание заказов согласно требованиям). * **Нефункциональное тестирование** проверяет, *как* система это делает (скорость работы при нагрузке, безопасность данных, удобство интерфейса, поведение на мобильных устройствах).
Тестирование юзабилити оценивает степень удобства использования приложения для конечного пользователя. Оцениваются интуитивность интерфейса, легкость выполнения задач, скорость навигации и удовлетворенность пользователя продуктом.
Тестирование безопасности выявляет уязвимости ПО, защищает данные от несанкционированного доступа и внешних атак. Проверяются авторизация, шифрование данных, защита от инъекций (SQL Injection, XSS) и соответствие стандартам безопасности.
Качество тестирования оценивается с помощью метрик: * **Defect Leakage (утечка дефектов)**: Процент багов, найденных пользователями в продакшене по сравнению с найденными в ходе тестирования. * **Test Coverage (покрытие тестами)**: Доля требований, покрытых тест-кейсами. * **Defect Density (плотность дефектов)**: Количество дефектов на объем кодовой базы или функционал системы.
* **CSS-селекторы**: Работают быстрее в большинстве браузеров, синтаксис проще и читаемее. Являются стандартом де-факто для веб-разработчиков. * **XPath**: Имеет более мощный функционал. Позволяет искать элементы по тексту (`//button[text()='Войти']`), перемещаться вверх к родительским элементам (`/..`) и использовать сложные логические условия. XPath незаменим при работе с динамическим сложным DOM, где нет четких ID и классов.
* **Implicit Waits (Неявные)**: Задаются один раз на всю сессию драйвера. Драйвер будет автоматически ждать появления любого элемента указанное время перед выбросом `NoSuchElementException`. Минус: замедляет тесты при проверке отсутствия элементов. * **Explicit Waits (Явные)**: Задаются точечно для конкретного элемента и конкретного условия (например, ждать пока кнопка станет кликабельной или исчезнет лоадер). Работает быстрее и гибче, является рекомендуемым подходом.
Page Object Model — паттерн проектирования автотестов, разделяющий логику тестов и структуру интерфейса: * Каждая веб-страница описывается отдельным классом (Page Object). * Поля этого класса хранят локаторы элементов страницы (кнопки, поля ввода). * Методы класса описывают действия на странице (например, `login(user, pass)`). * Сами тестовые сценарии используют методы Page Object. При изменении верстки страницы нужно обновить только локаторы в одном классе, сами тесты не ломаются.
В отличие от старого Selenium, Playwright выполняет проверку готовности элемента (Actionability checks) автоматически перед каждым действием (клик, ввод текста). Он проверяет: 1. Видим ли элемент (visible). 2. Стабилен ли элемент (не находится в процессе анимации движения). 3. Принимает ли события (не перекрыт другими элементами). 4. Активен ли он (enabled). Благодаря этому тесты работают стабильно без ручного прописывания явных ожиданий sleep/wait.
* **Session-based (куки)**: После входа сервер создает сессию в памяти/БД и возвращает клиенту идентификатор сессии в куке `Set-Cookie`. Тестировщик должен проверять куки, их флаги безопасности (`HttpOnly`, `Secure`, `SameSite`). * **Token-based (JWT)**: Сервер возвращает подписанный токен (например, Access/Refresh Token). Клиент сохраняет его и прикрепляет к каждому запросу в заголовок `Authorization: Bearer <token>`. Сервер не хранит состояние сессии (Stateless).
SQL-инъекция — уязвимость, возникающая из-за некорректной фильтрации входных данных, когда пользовательский ввод вставляется напрямую в SQL-запрос. Это позволяет злоумышленнику выполнить произвольный SQL-код. * **Тестирование**: Ввести в поля ввода или параметры URL спецсимволы (одинарную кавычку `'`, логические выражения `' OR 1=1 --`). Если приложение выдает системную ошибку БД или отображает скрытые данные пользователей, уязвимость присутствует.
XSS — уязвимость, позволяющая внедрить вредоносный JavaScript-код в веб-страницу, которая затем выполнится в браузере другого пользователя при ее посещении. * **Виды**: 1. **Stored (Хранимая)**: Скрипт сохраняется в БД (например, в тексте комментария) и отображается всем посетителям. 2. **Reflected (Отраженная)**: Скрипт передается в параметре запроса и сразу возвращается сервером на страницу. 3. **DOM-based**: Скрипт выполняется из-за некорректной обработки данных скриптами самой страницы.
Автотесты встраиваются в этапы сборки проекта для раннего обнаружения багов (Fail Fast): * **Pull Request**: При создании PR запускаются быстрые Unit-тесты и линтеры. Слияние веток блокируется при их падении. * **Merge в main**: Запускаются интеграционные и Smoke UI-тесты на тестовом окружении (staging). * **Перед релизом**: Запуск полного регрессионного сьюта тестов.
Docker позволяет запустить автотесты в изолированных контейнерах с идентичным окружением на любой машине (локально у разработчика или на сервере CI/CD): * Исключает проблему «у меня работает, а на сервере нет». * Позволяет параллельно запускать тесты в разных версиях браузеров (например, используя готовые контейнеры Selenium Grid или Selenoid). * Легко поднимает чистую тестовую базу данных перед началом тестов.
Мутационное тестирование оценивает **качество самих тестов**: 1. Специальный инструмент вносит небольшие случайные изменения (мутации) в исходный код программы (например, меняет `>` на `<`, или `+` на `-`). 2. Запускается сьют автотестов. 3. Если тесты упали — мутант «убит» (тесты качественные). Если все тесты прошли успешно — мутант «выжил» (тесты плохие, так как они не заметили изменение логики программы).
Статический анализ проверяет исходный код программы без его запуска. Инструменты (Linters, SonarQube) ищут: * Нарушения стандартов форматирования кода (Style guides). * Потенциальные баги и уязвимости безопасности (Code Smells, Vulnerabilities). * Дублирование кода. * Степень покрытия кода тестами. Это помогает улучшать качество кода на ранних этапах.
Помимо стандартных шагов и ожидаемого результата, мобильный баг-репорт должен содержать: * Точную модель устройства и версию ОС (например, Samsung Galaxy S21, Android 13). * Тип подключения (Wi-Fi, 4G, офлайн). * Логи с устройства, собранные во время сбоя (через `adb logcat` для Android или Console/Crash Logs для iOS). * Видеозапись экрана с отображением нажатий (touches).
* **Тестирование прерываний (Interrupt Testing)**: Проверка поведения приложения при входящих звонках, SMS, пуш-уведомлениях, разряде батареи, потере сети. * **Тестирование жестов (Gestures)**: Проверка корректности свайпов, зума двумя пальцами (pinch-to-zoom), двойных тапов. * **Тестирование энергопотребления**: Проверка, не перегревает ли приложение устройство и не разряжает ли батарею в фоновом режиме.
* **Нативные (Native)**: Написаны на языках платформы (Swift для iOS, Kotlin для Android). Быстрые, имеют доступ ко всем датчикам и API ОС. * **Мобильный веб (Mobile Web)**: Обычный сайт, адаптированный под экраны смартфонов. Открывается в мобильном браузере. * **Гибридные (Hybrid)**: Нативные приложения-оболочки, внутри которых отображается веб-контент (через WebView). Пишутся на кроссплатформенных фреймворках (React Native, Flutter).
Снифферы перехватывают HTTP/HTTPS трафик между мобильным устройством/браузером и сервером. Тестировщик может: * Проверять форматы запросов и ответов API. * Использовать инструмент **Breakpoints** для подмены ответов сервера на лету (например, вернуть ошибку 500 для проверки обработки ошибок в UI). * Использовать **Map Local** для подмены ответов локальными JSON-файлами.
Контрактное тестирование проверяет интеграцию между сервисами (поставщиком API — Provider и потребителем — Consumer) без развертывания всей микросервисной сети. Стороны согласовывают контракт (схему запросов и ответов). Потребитель проверяет, что его код корректно обрабатывает контракт, а поставщик — что его API не нарушает контракт при изменениях кода.
1. Определить профиль нагрузки на основе аналитики продакшена (сколько пользователей заходят на какие эндпоинты в пиковые часы). 2. Сформулировать цели (например, время ответа API < 200 мс при 5000 RPS). 3. Написать сценарии нагрузки в инструментах (k6, JMeter, Gatling). 4. Запустить тесты на изолированном стенде (не на живом проде). 5. Проанализировать узкие места (загрузка CPU серверов, утечки памяти, медленные SQL-запросы в БД).
Тестирование доступности гарантирует удобство использования сайта людьми с ограниченными возможностями (зрение, слух, моторика): * Проверить контрастность текста и элементов дизайна. * Проверить доступность навигации по сайту только с помощью клавиатуры (клавиша Tab). * Проверить наличие корректных ARIA-атрибутов и `alt` описаний у картинок для работы программ чтения экрана (Screen Readers).
SBTM — метод управления исследовательским тестированием. Вместо хаотичных проверок тестирование разбивается на фиксированные временные сессии (обычно от 60 до 120 минут) с четко очерченной целью (хартией тестирования). По итогам сессии тестировщик заполняет отчет: что проверено, какие баги найдены, сколько времени ушло на настройку окружения и сколько на сам поиск ошибок.
Ретроспектива — это встреча для улучшения процессов, а не поиска виновных. QA должен: * Подсветить системные проблемы качества (например, требования часто меняются в середине спринта, из-за чего тесты приходится переписывать на лету). * Предложить улучшения (например, внедрить критерии готовности задач Definition of Ready перед передачей в разработку). * Поделиться успехами (например, сокращением времени прохождения автотестов).