Основы тестирования ПО: теория и практика

Введение в тестирование

Тестирование — это процесс проверки соответствия фактического результата работы системы ожидаемому. Тестировщик выступает в роли пользователя, выявляя проблемы до того, как их увидит конечный клиент. Его задача — не только найти баги, но и проанализировать удобство использования системы, предлагая улучшения.

Пример: При тестировании кнопки «Оформить заказ» проверяется не только успешное создание заказа, но и поведение системы при вводе некорректных данных (неверный номер телефона, вымышленный пользователь).

Ключевая цель тестировщика — умно проверять самые важные для бизнеса и пользователя сценарии, экономя время и деньги компании, а не «протыкать всё».

QA, QC и Тестировщик: терминология

  • QA (Quality Assurance) — обеспечение качества. Фокус на процессах, направленных на предотвращение дефектов на ранних этапах разработки (анализ требований, улучшение процессов).
  • Тестировщик — фокус на поиске дефектов в готовом или почти готовом продукте, проверке по документации.
  • QC (Quality Control) — контроль качества. Менее распространённая роль, часто сливается с QA.

На практике в СНГ термины «QA» и «тестировщик» часто используются как взаимозаменяемые, но понимать концептуальную разницу между предотвращением и поиском ошибок важно.

Основные принципы тестирования

  1. Исчерпывающее тестирование невозможно. Нужно проверять самые важные сценарии, используя техники тест-дизайна для оптимизации усилий.
  2. Раннее тестирование. Подключение к процессу как можно раньше (например, на этапе обсуждения требований) позволяет находить и исправлять ошибки дешевле и быстрее.
  3. Парадокс пестицида. Если постоянно использовать одни и те же тесты, их эффективность со временем падает. Тестовые сценарии и данные необходимо периодически обновлять.
  4. Тестирование зависит от контекста. Подходы и проверки различаются для мобильного приложения, веб-сайта или игры (например, возраст игрового персонажа может быть 110 лет, что для обычной формы регистрации было бы ошибкой).
  5. Скопление дефектов. Часто большинство критических ошибок сосредоточено в одном модуле или функциональности.
  6. Тестирование показывает наличие дефектов, но не может доказать их отсутствие.
  7. Заблуждение об отсутствии ошибок. Даже если тестирование прошло успешно, это не гарантирует, что в системе нет скрытых проблем.

Жизненные циклы: SDLC и STLC

SDLC (Жизненный цикл разработки ПО)

Этапы пути функции от идеи до поддержки:

  1. Идея → 2. Требования (анализ и документирование) → 3. Дизайн (создание макетов) → 4. Разработка (написание кода) → 5. Тестирование → 6. Релиз (выпуск для пользователей) → 7. Поддержка (мониторинг и доработки) / Смерть продукта.

Тестировщик по-хорошему должен подключаться уже на этапе требований (принцип раннего тестирования).

STLC (Жизненный цикл тестирования)

Этапы процесса тестирования:

  1. Анализ требований → 2. Планирование (тест-план) → 3. Разработка тест-кейсов → 4. Настройка окружения → 5. Выполнение тестирования → 6. Отчётность.

Верификация и валидация

  • Верификация: «Мы сделали продукт правильно?» (Соответствие техзаданию и требованиям).
  • Валидация: «Мы сделали правильный продукт?» (Решает ли продукт реальную задачу пользователя/бизнеса).

Пример: Велосипед с квадратными колёсами. По требованиям (квадратные колёса) — верификация пройдена. Поехать на нём нельзя — валидация провалена.

Тестирование методом ящика

  • Чёрный ящик: Тестирование без знания внутреннего устройства системы, как обычный пользователь (только UI, ввод/вывод данных).
  • Белый ящик: Тестирование с полным знанием кода и архитектуры системы (проверка на уровне кода).
  • Серый ящик: Комбинация: нет доступа к коду, но есть доступ к внутренним данным (логи, БД, API).

Тестирование требований

Требования должны соответствовать критериям:

  • Полнота (отсутствие нераскрытых вопросов).
  • Однозначность (исключает двоякое толкование, например, «быстро» → «менее 2 секунд»).
  • Непротиворечивость (отсутствие конфликта между требованиями).
  • Необходимость (описывает суть, а не детали дизайна).
  • Осуществимость (техническая реализуемость).
  • Тестируемость (можно объективно проверить «прошло/не прошло»).

Тестовая документация

Зачем нужна: Чтобы ничего не забыть, для onboarding новых членов команды, для быстрой регрессионной проверки, для отчётности и оформления баг-репортов.

Виды документации:

  • Чек-лист: Список проверок («что проверить»). Быстро составляется и выполняется, но может быть недостаточно детальным.
  • Тест-кейс: Детальное описание шагов для проверки конкретного сценария («как проверить» и ожидаемый результат). Более понятен команде, но требует больше времени на написание.
  • Тест-план: Документ верхнего уровня, описывающий подход, объём, сроки, риски и ресурсы для тестирования всего релиза. Составляет руководитель тестирования.
  • Баг-репорт: Документ, описывающий найденную ошибку. Должен быть кратким, чётким и содержать шаги для воспроизведения, фактические и ожидаемые результаты, окружение, severity (серьёзность) и priority (приоритет).

Окружения (Environments)

Копии системы для разных этапов работы:

  1. Dev/Development: Среда разработчиков для первичной проверки изменений. Нестабильна.
  2. Test/QA: Основная среда для тестировщиков. Здесь проводят полноценное тестирование.
  3. Stage/Pre-production: Максимально точная копия продакшена. Для финальной проверки перед выпуском.
  4. Production: Боевая среда с реальными пользователями и данными. Тестирование запрещено, только мониторинг.

Основы веб-архитектуры

Клиент-серверная архитектура и HTTP

  • Клиент (браузер, приложение) отправляет запрос (request).
  • Сервер обрабатывает запрос, при необходимости обращается к Базе Данных и возвращает ответ (response).
  • HTTP/HTTPS — протокол общения между клиентом и сервером.

Основные группы HTTP-статусов:

  • 2xx — Успех (200 OK, 201 Created).
  • 3xx — Перенаправление (редирект).
  • 4xx — Ошибка клиента (400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found).
  • 5xx — Ошибка сервера (500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable).

Идентификация, Аутентификация, Авторизация

  1. Идентификация: «Кто я?» (Логин, email, телефон).
  2. Аутентификация: «Это действительно я?» (Подтверждение паролем, кодом из SMS, Face ID). Двухфакторная аутентификация (2FA) добавляет ещё один уровень проверки.
  3. Авторизация: «Что мне можно?» (Права доступа, например, пользователь vs администратор).

API (Application Programming Interface)

Интерфейс взаимодействия между программами. Упрощает общение фронтенда (интерфейс) с бэкендом (логика и данные) и между микросервисами.

REST (REpresentational State Transfer) — популярный архитектурный стиль для построения API, основанный на HTTP-методах:

  • GET — получить данные (идемпотентный, кэшируемый, нет тела запроса).
  • POST — создать/отправить данные (НЕ идемпотентный, есть тело запроса).
  • PUT — полное обновление данных.
  • PATCH — частичное обновление данных.
  • DELETE — удалить данные.

Идемпотентность — свойство, при котором многократное выполнение одной и той же операции приводит к одинаковому результату (GET, PUT, DELETE — идемпотентны; POST — нет).

Сравнение PUT и PATCH

  • PUT (полное обновление): Заменяет всю сущность целиком. Например, при обновлении имени пользователя через PUT, все остальные поля (фамилия, телефон) могут стать пустыми, если не были переданы в запросе.
  • PATCH (частичное обновление): Изменяет только указанные поля. При обновлении имени через PATCH остальные данные пользователя сохраняются.

Кэш (Cache)

Кэш — это временное хранилище данных, используемое для ускорения повторной загрузки информации без запроса к серверу или базе данных.

Где используется и преимущества:

  • Браузерный кэш: Сохраняет статические файлы (картинки, CSS, JavaScript) с посещённых сайтов.
  • Преимущества:
    • Быстрая загрузка страниц при повторном посещении.
    • Меньше нагрузки на сервер.
    • Экономия трафика пользователя.
    • Стабильная работа при высокой нагрузке (например, во время акций).

Работа с кэшем в браузере:

  1. Просмотр кэшированных запросов: В DevTools (F12) → вкладка Network. В колонке Size можно увидеть from disk cache или from memory cache.
  2. Отключение кэша: В той же вкладке Network есть опция Disable cache.
  3. Принудительное обновление кэша: Сочетание клавиш Ctrl + F5 (hard refresh).

Практические проблемы с кэшем:

  • Для тестировщика: После обновления кода разработчиком (например, текста кнопки) в браузере может отображаться старая версия из кэша. Решение — очистка кэша (Ctrl+F5).
  • Для пользователя: После обновления цен на сайте у пользователя могут отображаться старые цены из кэша. Частая рекомендация службы поддержки — "очистите кэш".

Cookies (Куки)

Куки — это небольшие фрагменты данных, которые сайт сохраняет в браузере пользователя для его идентификации и хранения информации о сессии и предпочтениях.

Что хранят куки?

  • Session ID: Уникальный идентификатор сессии, позволяющий не вводить логин/пароль при повторном входе на сайт (например, во ВКонтакте).
  • Данные корзины товаров: Сохранение товаров в корзине даже после закрытия браузера.
  • Пользовательские настройки: Язык интерфейса, валюта, тема оформления (светлая/тёмная), которые подтягиваются автоматически.
  • Данные для аналитики: Информация о действиях пользователя на сайте (с согласия пользователя) для сбора статистики и таргетированной рекламы.

Использование кук в тестировании:
Тестировщик может использовать куки для:

  • Тестирования продукта с точки зрения конкретного пользователя (с его настройками, корзиной).
  • Воспроизведения пользовательского опыта (User Experience).
  • Просмотра и управления куками через DevTools → вкладка Application → раздел Cookies.

Важно: Куки имеют срок жизни и могут быть удалены.

Архитектура проектов

Монолитная архитектура

  • Весь продукт — это единая, неразделимая система (один сервер, один релиз).
  • Плюсы: Дешевле в разработке на начальном этапе, проще для понимания новичками.
  • Минусы: При поломке в одном модуле страдает вся система. Любое изменение требует обновления всего монолита.

Микросервисная архитектура

  • Система разделена на множество независимых сервисов, каждый из которых отвечает за свою бизнес-функцию (например, отдельные сервисы: пользователи, заказы, оплата, доставка).
  • Плюсы: Отказ одного сервиса не ломает всю систему. Упрощает работу команд над разными частями продукта.
  • Минусы: Более сложная архитектура. Проблемы часто возникают не внутри сервиса, а в межсервисном взаимодействии. Для тестировщика усложняется задача, так как нужно проверять цепочки между сервисами.

Виды тестирования

По цели тестирования

  • Функциональное тестирование: Проверка, что функция работает в соответствии с требованиями (например, создание заказа).
  • Нефункциональное тестирование: Проверка качества продукта (скорость, безопасность, удобство).

Основные нефункциональные виды

  • UI-тестирование: Проверка интерфейса, вёрстки, соответствия макетам (адаптивность, наложение элементов).
  • UX-тестирование: Проверка удобства и понятности интерфейса для пользователя.
  • Security-тестирование: Проверка защищённости системы и контроля доступа.
  • Локализация: Проверка корректности перевода, форматов дат, валют.
  • Performance-тестирование: Проверка скорости работы системы и времени отклика.
  • Тестирование стабильности: Проверка работы системы при обычном использовании.
  • Стресс-тестирование: Резкое увеличение нагрузки для поиска точки отказа системы.
  • Нагрузочное тестирование: Постепенное увеличение нагрузки (количества пользователей) для оценки стабильности.

Группа тестов, связанных с изменениями

  • Дымовое тестирование (Smoke Test): Быстрая проверка основных функций системы после сборки. Если провалено — дальнейшее тестирование не имеет смысла. Длится 5-15 минут.
  • Санитарное тестирование (Sanity Test): Узкая, углублённая проверка конкретного модуля после внесения изменений (например, после исправления бага), чтобы убедиться, что исправление работает и ничего рядом не сломалось.
  • Регрессионное тестирование: Проверка старого функционала после добавления нового или внесения изменений. Цель — убедиться, что нововведение ничего не сломало. Проводится перед релизом.
    • Регрессионный набор — заранее подготовленный набор тест-кейсов для таких проверок.
  • Повторное тестирование (Re-test): Проверка конкретного бага после того, как разработчик сообщил об его исправлении.

Другие классификации

  • По доступу к системе: Чёрный, серый, белый ящик.
  • По типу сценариев: Позитивные (валидные данные) и негативные (невалидные данные).
  • По автоматизации: Ручное и автоматизированное тестирование.
  • По исполнению кода: Статическое (анализ требований/кода без запуска) и динамическое (тестирование работающей системы).

Техники тест-дизайна

Тест-дизайн — это выбор разумных и эффективных проверок, экономящих время без потери качества.

Ключевые техники

  1. Классы эквивалентности (Эквивалентное разбиение)

    • Суть: Разделение всех возможных входных значений на группы (классы), которые система должна обрабатывать одинаково. Для тестирования достаточно взять по одному значению из каждого класса.
    • Пример (поле "Возраст: 18-60"):
      • Валидный класс: [18, 60] (например, 25).
      • Невалидный класс 1: <18 (например, 17).
      • Невалидный класс 2: >60 (например, 61).
      • Доп. класс: нечисловые значения (буквы).
  2. Граничные значения (Анализ граничных значений)

    • Суть: Тестирование на границах допустимых диапазонов и рядом с ними, так как именно там чаще всего возникают ошибки.
    • Пример (границы 18 и 60):
      • Для границы 18 проверяем: 17 (ошибка), 18 (успех), 19 (успех).
      • Full Value — проверка трёх значений (как в примере).
      • Two Value — проверка только значений по разные стороны границы (17 и 18).
  3. Таблица принятия решений

    • Суть: Используется, когда результат зависит от комбинации нескольких условий. Позволяет наглядно описать все сценарии.
    • Пример: Применение скидки в зависимости от условий: "Купон введён?", "Купон валидный?", "Сумма корзины >1000?".
  4. Предугадывание ошибок

    • Суть: Проверка системы на основе опыта тестировщика о том, как пользователь может её "сломать" (например, оставить обязательное поле пустым, ввести очень длинный текст, добавить пробелы).
  5. Попарное тестирование (Pairwise)

    • Суть: Проверка не всех возможных комбинаций параметров, а минимального набора, где каждая пара значений встречается хотя бы раз. Резко сокращает количество тестов.
    • Пример: Тестирование комбинаций "Браузер x Способ оплаты x Способ доставки". Вместо 8 полных комбинаций можно проверить 4.
  6. Тестирование переходов состояний

    • Суть: Проверка корректности перехода объекта (например, заказа) между его статусами по бизнес-правилам.
    • Пример для заказа: "Создан" → "Оплачен" → "В доставке" → "Доставлен". Нужно проверить как разрешённые переходы, так и невозможные (например, "Создан" → "Доставлен").

На практике чаще всего используются классы эквивалентности и анализ граничных значений, а предугадывание ошибок добавляется как бонус. Выбор техники зависит от контекста задачи.

Пирамида тестирования

Пирамида тестирования — модель, визуализирующая соотношение стоимости, времени и количества тестов разных уровней. Конкретный вид пирамиды может меняться в зависимости от проекта.

Классическая пирамида (снизу вверх)

  1. Юнит-тесты (Unit Tests): Проверки отдельных модулей кода, пишутся разработчиками. Самые дешёвые, быстрые и многочисленные.
  2. Интеграционные тесты (Integration Tests): Проверка взаимодействия между несколькими компонентами или сервисами (например, через API).
  3. Системные тесты (System Tests): Проверка всей интегрированной системы как целого.
  4. Приёмочные тесты (E2E / Acceptance Tests): Проверка полных пользовательских сценариев (от начала до конца) с точки зрения бизнес-требований или конечного пользователя/заказчика.

Вывод: Для ручного тестировщика наиболее релевантны уровни интеграционного, системного и приёмочного (E2E) тестирования, где проверяются взаимодействия сервисов, работа системы в целом и пользовательские сценарии.