Углубленное тестирование веб-приложений: от архитектуры до технического интервью

Курс предназначен для подготовки QA-инженеров к реальной проектной деятельности через освоение инструментария и понимание клиент-серверного взаимодействия. Программа охватывает полный цикл технического тестирования: от анализа трафика и API до диагностики сложных дефектов.

1. Архитектура веб-приложений и протокол HTTP: фундамент взаимодействия клиента и сервера

Архитектура веб-приложений и протокол HTTP: фундамент взаимодействия клиента и сервера

Представьте, что вы нажимаете кнопку «Оплатить» в корзине интернет-магазина. Через долю секунды на экране появляется подтверждение, а на почту приходит чек. Для обычного пользователя это магия одного клика. Для QA-инженера это каскад событий: браузер формирует пакет данных, DNS-сервер ищет IP-адрес, устанавливается TCP-соединение, летит HTTP-запрос, отрабатывают балансировщики нагрузки, микросервисы авторизации и биллинга, база данных фиксирует транзакцию, а фронтенд интерпретирует JSON-ответ. Если на любом из этих этапов произойдет сбой, тестирование «методом тыка» не поможет найти причину. Чтобы локализовать баг — понять, «отвалился» ли это скрипт на клиенте или база данных на сервере ушла в тайм-аут — необходимо досконально понимать анатомию веб-архитектуры.

Клиент-серверная модель: кто за что отвечает

В основе любого современного веб-ресурса лежит клиент-серверная архитектура. Это модель взаимодействия, где одна сторона (клиент) запрашивает ресурс или услугу, а другая (сервер) — предоставляет её. В тестировании веб-приложений «клиентом» чаще всего выступает браузер (Chrome, Safari, Firefox), но им также может быть мобильное приложение или другой сервер, обращающийся к API.

Тонкий и толстый клиент

Исторически веб-приложения прошли путь от «тонких» клиентов к «толстым». В эпоху Web 1.0 браузер был лишь средством отображения статического HTML, который сервер присылал в готовом виде. Сегодня ситуация иная: * Клиентская часть (Frontend): отвечает за интерфейс, логику отображения, валидацию полей ввода на лету и хранение временных состояний. Современные фреймворки (React, Vue, Angular) превращают браузер в мощную вычислительную среду. * Серверная часть (Backend): отвечает за бизнес-логику, безопасность, обработку тяжелых вычислений и работу с данными. Сервер — это «черный ящик» для пользователя, доступ к которому осуществляется через строго определенные интерфейсы.

Для тестировщика это разделение критично. Если при нажатии на кнопку ничего не происходит, первым делом мы смотрим в консоль браузера. Если там ошибка ReferenceError — виноват фронтенд (ошибка в коде JS). Если же мы видим сетевой запрос со статусом 500 Internal Server Error — проблема на бэкенде, и нужно идти изучать серверные логи.

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

Реальные приложения редко состоят из одной программы на одном сервере. Обычно это структура из нескольких слоев, каждый из которых может стать точкой отказа.

  • Уровень представления (Presentation Layer): то, что видит пользователь. Здесь мы тестируем верстку, кроссбраузерность и UI-логику.
  • Уровень логики (Application/Business Layer): здесь живут алгоритмы. Например, расчет стоимости доставки с учетом веса и региона. Этот уровень может быть размазан между фронтендом и бэкендом.
  • Уровень данных (Data Layer): базы данных (SQL/NoSQL) и файловые хранилища. Здесь тестировщик проверяет, правильно ли сохранились данные после регистрации или не пропал ли товар из корзины после перезагрузки страницы.
  • Микросервисы против монолитов

    Современный тренд — переход от монолитной архитектуры (когда всё приложение — это один огромный кусок кода) к микросервисной. В микросервисах каждая функция (поиск, корзина, профиль) — это отдельное мини-приложение. * Плюс для QA: можно тестировать компоненты изолированно. * Минус для QA: сложность интеграционного тестирования возрастает. Нужно проверять, как сервисы общаются между собой, что происходит, если один из десяти сервисов «упал», и как это отразится на пользователе.

    Протокол HTTP: язык, на котором говорит интернет

    HTTP (HyperText Transfer Protocol) — это протокол прикладного уровня, работающий по принципу «запрос-ответ». Он является «безсостоянийным» (stateless). Это означает, что сервер не обязан помнить о предыдущем запросе клиента. Каждый запрос для него — как первый. Чтобы сервер «узнал» вас (например, понял, что вы уже залогинены), используются дополнительные механизмы: куки (cookies), сессии и токены.

    Структура HTTP-запроса

    Когда вы вводите URL в строку браузера, формируется текстовое сообщение. Тестировщику важно уметь читать его «глазами», чтобы понимать, какие данные уходят на сервер.

  • Стартовая строка (Start Line): содержит метод, путь к ресурсу и версию протокола.
  • Пример: GET /api/v1/products HTTP/1.1
  • Заголовки (Headers): метаданные запроса.
  • * Host: адрес сервера. * User-Agent: информация о браузере и ОС. * Content-Type: формат данных в теле (например, application/json). * Authorization: токен для доступа к закрытым разделам.
  • Тело запроса (Body): данные, которые мы передаем. В методе GET тела обычно нет, а в POST там может быть JSON с данными нового пользователя.
  • Методы HTTP (Verbs)

    Методы определяют желаемое действие над ресурсом. На интервью часто просят объяснить разницу между ними, особенно в контексте REST API.

    * GET: Запрашивает данные. Не должен менять состояние сервера. Считается «безопасным» и «идемпотентным» (сколько раз ни запрашивай — результат один, данных на сервере не прибавится). * POST: Создает новый ресурс. Например, регистрация нового аккаунта. Не является идемпотентным: два нажатия на кнопку «Создать» могут создать двух одинаковых пользователей, если на бэкенде нет защиты. * PUT: Обновляет существующий ресурс целиком. Если вы меняете профиль и отправляете PUT, вы должны прислать все поля объекта. Если какое-то поле пропустить, оно может затереться в базе (стать null). * PATCH: Частичное обновление. Позволяет изменить только одно поле, например, только фамилию, не трогая остальные данные. * DELETE: Удаляет ресурс.

    Нюанс для QA: Разработчики иногда используют POST для всего подряд. Это плохая практика (нарушение семантики протокола), которая усложняет кэширование и диагностику. Тестировщик должен указывать на такие несоответствия документации.

    Коды ответов сервера: диагностика за одну секунду

    Ответ сервера также состоит из стартовой строки (со статусом), заголовков и тела (обычно это HTML-страница или JSON). Код ответа — это первая цифра, на которую смотрит QA.

    | Группа кодов | Значение | Что это значит для тестировщика? | | :--- | :--- | :--- | | 1xx | Информационные | Встречаются редко, говорят о продолжении процесса. | | 2xx | Успех | Всё хорошо. Самый частый — 200 OK, для создания — 201 Created. | | 3xx | Перенаправление | Ресурс переехал. Например, 301 Moved Permanently. | | 4xx | Ошибка клиента | Вы (клиент) сделали что-то не так. Неверный URL (404), нет прав (403), не авторизован (401), плохие данные в запросе (400). | | 5xx | Ошибка сервера | Сервер «сломался». Ошибка в коде бэкенда (500), сервер перегружен (503), отвалился шлюз (504). |

    Кейс из практики: 400 vs 500

    Вы тестируете форму регистрации. Вводите в поле «Возраст» текст «двадцать лет» вместо цифр. * Если сервер вернул 400 Bad Request с текстом «Поле должно быть числом» — это правильная работа бэкенда. * Если сервер вернул 500 Internal Server Error — это баг бэкенда. Сервер не ожидал текста, «упал» в необработанное исключение и выдал общую ошибку. Это потенциальная уязвимость и признак плохого качества кода.

    URL и DNS: как браузер находит сервер

    URL (Uniform Resource Locator) — это не просто строчка, а структурированный адрес. Пример: https://shop.example.com:443/search?q=phone#specs

    * https: протокол (схема). * shop: поддомен. * example.com: домен второго уровня. * 443: порт (для HTTPS стандартный 443, для HTTP — 80). * /search: путь (path) к ресурсу. * ?q=phone: параметры запроса (query parameters). * #specs: якорь (фрагмент), используется фронтендом для навигации внутри страницы.

    DNS (Domain Name System) — это «телефонная книга» интернета. Компьютеры не понимают слов google.com, им нужны IP-адреса (например, 142.250.185.78). Когда вы вводите домен, браузер сначала спрашивает у DNS-сервера: «Какой IP у этого имени?». Для тестировщика важно знать о файле hosts на локальном компьютере. С его помощью можно принудительно сопоставить домен с нужным IP. Это полезно, когда нужно протестировать новую версию сайта, которая еще не «раскатана» на основной домен, но уже лежит на тестовом сервере.

    Модель OSI для веб-тестировщика

    Хотя веб-приложения работают на самом верхнем уровне (прикладном), понимание того, что происходит «под капотом», помогает в тестировании производительности и безопасности. Модель OSI состоит из 7 уровней, но для QA наиболее важны три:

  • L7 (Прикладной): Здесь живет HTTP/HTTPS. Мы тестируем API, заголовки, JSON.
  • L4 (Транспортный): Протоколы TCP и UDP. TCP гарантирует доставку пакетов в нужном порядке. Если у пользователя «лагает» сайт из-за потерь пакетов на плохом Wi-Fi — это проблемы на уровне L4.
  • L3 (Сетевой): Уровень IP-адресов и маршрутизации.
  • Когда мы говорим о «тестировании на уровне протокола», мы имеем в виду проверку того, как данные упаковываются и передаются. Например, HTTPS — это тот же HTTP, но «завернутый» в шифрованный туннель TLS/SSL.

    TLS/SSL: почему это важно для QA

    HTTPS обеспечивает: * Шифрование: никто не перехватит ваш пароль в публичном Wi-Fi. * Целостность: данные не будут изменены по пути. * Аутентификацию: вы уверены, что общаетесь именно с сервером банка, а не с его имитацией.

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

    Взаимодействие через API: REST и JSON

    Большинство современных веб-приложений общаются между фронтендом и бэкендом через REST API. REST (Representational State Transfer) — это архитектурный стиль, который диктует, как должны выглядеть URL и методы. Основные принципы REST:

  • Ресурсы: всё есть ресурс (пользователь, заказ, товар). У ресурса есть уникальный URL.
  • Единообразие: для получения списка пользователей всегда используется GET /users, для создания — POST /users.
  • Отсутствие состояния: сервер не хранит контекст между запросами.
  • Данные в REST чаще всего передаются в формате JSON (JavaScript Object Notation). Это текстовый формат, который легко читается и человеком, и машиной.

    Пример объекта JSON:

    Тестировщик API проверяет: * Типы данных (что цена — это число, а не строка). * Обязательность полей (что нельзя создать товар без названия). * Структуру ответа (соответствует ли она документации в Swagger).

    Синхронные и асинхронные запросы: AJAX

    Раньше для обновления одной цифры на странице нужно было перезагружать её целиком. Сейчас используется AJAX (Asynchronous JavaScript and XML). Несмотря на название, вместо XML сейчас почти всегда JSON. Асинхронность означает, что браузер отправляет запрос в фоновом режиме, а пользователь продолжает работать с интерфейсом. Когда ответ приходит, JavaScript обновляет конкретный кусочек страницы.

    Что это значит для тестирования? Появляются специфические баги — «состояния гонки» (Race Conditions). Например, пользователь нажал кнопку дважды очень быстро. Первый запрос задержался, второй пришел раньше. Если фронтенд не умеет это обрабатывать, данные могут отобразиться некорректно. Тестировщик должен проверять такие сценарии: блокируется ли кнопка после нажатия, показывается ли индикатор загрузки (spinner) и что будет, если интернет очень медленный.

    Статика и динамика: как ускорить загрузку

    Веб-приложение состоит из двух типов контента:

  • Статический контент: файлы, которые не меняются для разных пользователей (картинки, CSS-стили, шрифты, JS-файлы).
  • Динамический контент: то, что генерируется сервером индивидуально (ваша лента новостей, баланс кошелька).
  • Для оптимизации статику часто выносят на CDN (Content Delivery Network) — сеть серверов по всему миру. Когда пользователь из Владивостока открывает сайт, картинки грузятся с сервера в Хабаровске, а не из Москвы. Это сокращает задержки. В тестировании важно проверять, не «побились» ли пути к статике после деплоя. Если вы видите сайт без стилей (просто черный текст на белом фоне) — скорее всего, браузер не смог загрузить CSS-файл из-за ошибки 404 или проблем с правами доступа на сервере.

    Кэширование: палка о двух концах

    Кэширование — это сохранение копии ресурса для быстрого доступа. Кэш может быть: * В браузере: чтобы не качать логотип сайта каждый раз. * На сервере: чтобы не делать тяжелый запрос в базу данных каждую секунду.

    Для QA кэш — частый источник ложных багов или «невидимых» исправлений. * Ситуация А: Разработчик исправил баг в стилях, вы проверяете — баг на месте. На самом деле браузер взял старый файл из кэша. Нужно нажать Ctrl + F5 (полная очистка кэша страницы). * Ситуация Б: Вы нашли баг, позвали разработчика, а у него всё работает. Возможно, у него в кэше «удачная» версия данных.

    Понимание заголовков кэширования (например, Cache-Control) позволяет тестировщику проверять, насколько эффективно приложение работает с ресурсами пользователя.

    Идемпотентность и безопасность методов

    Вернемся к методам HTTP с точки зрения безопасности данных. * Идемпотентность — это свойство метода, при котором повторный запрос приводит к тому же результату, что и первый. * GET, PUT, DELETE — идемпотентны. Если вы удалите пользователя один раз — он удалится. Если второй раз — он уже удален, состояние системы не изменится (хотя код ответа может быть другим: 204 в первый раз и 404 во второй). * POSTне идемпотентен. Каждый запрос создает новый объект. * Безопасность — метод не меняет данные на сервере. * GET, HEAD, OPTIONS — безопасны. Они только читают. * POST, PUT, DELETE, PATCH — небезопасны.

    Тестировщик должен проверять, чтобы «безопасные» методы действительно ничего не ломали. Известны случаи, когда разработчики вешали удаление данных на GET-запрос. Это опасно: поисковый робот, индексирующий сайт, может просто «пройтись» по ссылкам и удалить всю базу данных.

    Жизненный цикл запроса: от клика до рендера

    Подводя итог, проследим путь запроса. Это классический вопрос на Senior-интервью: «Что происходит, когда вы вводите google.com в браузере?».

  • DNS-резолвинг: Браузер ищет IP-адрес домена.
  • Установление соединения: Происходит TCP-рукопожатие (Handshake). Если это HTTPS — добавляется TLS-рукопожатие для обмена ключами шифрования.
  • Отправка HTTP-запроса: Браузер формирует текст запроса с методом и заголовками.
  • Обработка на сервере:
  • * Запрос принимает веб-сервер (например, Nginx). * Он передает его приложению (Python, Java, Node.js). * Приложение идет в базу данных или кэш. * Формируется ответ (обычно JSON или HTML).
  • Доставка ответа: Сервер отправляет данные клиенту.
  • Рендеринг: Браузер парсит HTML, строит дерево элементов (DOM), загружает стили и скрипты, выполняет JavaScript и рисует пиксели на экране.
  • Для тестировщика каждый из этих пунктов — потенциальное место для поиска дефектов. На курсе мы научимся «вклиниваться» в этот процесс с помощью инструментов разработчика и прокси-серверов, чтобы видеть, изменять и ломать эти запросы, обеспечивая максимальное качество продукта.