Какой статус-код у HTTP-редиректа?

«Какой статус-код у HTTP-редиректа?» — вопрос из категории HTTP и веб-протоколы, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

HTTP-редиректы относятся к классу статус-кодов 3xx. Наиболее важные для тестировщика:

Код Название Семантика Кэшируется браузером? Критично для SEO?
301 Moved Permanently Постоянное перемещение ресурса на новый URI. Да Да (линковый вес передается новому URL)
302 Found (ранее Moved Temporarily) Временное перемещение. Клиент ДОЛЖЕН использовать оригинальный URI для будущих запросов. Нет (по спецификации) Нет
307 Temporary Redirect Временный редирект, но с гарантией, что метод и тело запроса не изменятся (в отличие от 302). Нет Нет
308 Permanent Redirect Постоянный редирект, аналогичный 301, но также гарантирующий сохранение метода и тела запроса. Да Да

Почему это важно в тестировании?

  1. Проверка логики приложения: Убедиться, что после действия (например, отправки формы) происходит корректный редирект (скажем, 302 на страницу успеха).
  2. Тестирование SEO и ссылок: Проверить, что старые URL возвращают 301, а не 404.
  3. Тестирование API: Некоторые API используют 3xx коды, и клиент должен их корректно обрабатывать.

Пример автотеста на Python с requests (с отключенным автоматическим следованием редиректам):

import requests
import pytest

def test_old_url_redirects_permanently():
    """Проверяем, что старый адрес профиля возвращает 301 на новый."""
    old_url = "https://example.com/old-profile-page"
    new_url = "https://example.com/user/profile"

    # Отключаем автоматические редиректы, чтобы проверить код ответа
    response = requests.get(old_url, allow_redirects=False)

    assert response.status_code == 301, f"Ожидался 301, получен {response.status_code}"
    # Проверяем заголовок Location
    assert "Location" in response.headers
    assert response.headers["Location"] == new_url

# Пример теста для временного редиректа после логина
@pytest.mark.ui  # Условная маркировка
class TestLoginFlow:
    def test_successful_login_redirects_to_dashboard(self, test_user, browser):
        login_page = LoginPage(browser)
        login_page.open()
        login_page.login(test_user.email, test_user.password)
        # После логина ожидаем временный редирект (302/307) на дашборд
        WebDriverWait(browser, 5).until(
            EC.url_to_be("https://example.com/dashboard")
        )
        # Можно также проверить, что текущий URL изменился, а исходный URL вернул бы 302
        assert "dashboard" in browser.current_url

Понимание различий между 301/308 и 302/307 критично для корректного тестирования поведения веб-приложений и REST API.