Каково типичное для вас соотношение тестирования Backend и Frontend?

Ответ

Типичное соотношение — ~70% Backend и ~30% Frontend тестирования.

Backend-фокус (70%):

  • Тестирование API (REST, GraphQL): валидация контрактов, статус-кодов, структуры ответов, бизнес-логики.
  • Работа с базами данных: проверка корректности записей после операций.
  • Интеграционное тестирование взаимодействия между сервисами.
  • Тестирование производительности и нагрузки на API.

Frontend-фокус (30%):

  • Проверка критичной пользовательской логики, связанной с бэкендом (отправка форм, обработка ошибок).
  • Валидация данных на стороне клиента.
  • Базовые проверки UI: соответствие макетам, кроссбраузерность ключевых сценариев.

Пример теста для Backend (создание пользователя через API):

import requests

def test_user_creation_api():
    """Тестирует эндпоинт создания нового пользователя."""
    url = "https://api.example.com/v1/users"
    payload = {
        "name": "John Doe",
        "email": "john.doe@example.com"
    }
    headers = {"Content-Type": "application/json"}

    response = requests.post(url, json=payload, headers=headers)

    # Проверяем успешный ответ
    assert response.status_code == 201
    response_data = response.json()
    assert "id" in response_data
    assert isinstance(response_data["id"], str)
    assert response_data["name"] == payload["name"]
    assert response_data["email"] == payload["email"]

    # (Дополнительно) Проверяем, что пользователь появился в БД
    # db_check_user_exists(response_data["id"]) ...

Фронтенд-тестирование часто сосредоточено на интеграционных точках с этим бэкендом.

Ответ 18+ 🔞

Ну вот смотри, как оно обычно бывает в этой нашей прекрасной профессии. Все эти разговоры про "фуллстек тестировщика" — это, конечно, красиво, но на деле-то всё проще, как бутерброд с колбасой. Основной кусок мяса, то есть работы, это бэкенд, примерно 70%.

Почему? Да потому что там, в этих тёмных дебрях серверов, и происходит вся магия, а иногда и пиздец. Фронтенд — это просто красивая обёртка, которая иногда криво сворачивается.

Так, бэкенд, наша любовь и боль (эти самые 70%):

  • APIшники всякие (REST, GraphQL): Ты там контракты валидируешь, смотришь, чтобы статус-коды не хуйню какую-то возвращали, а то вдруг вместо 404 тебе 200 и пустой экран прилетит. Проверяешь, чтобы логика бизнес-логикой была, а не абы чем.
  • Базы данных, ёпта: Сделал запрос — пошёл в БД, посмотрел, записалось ли чёрт побери. Или удалилось. А то бывает нажал "удалить", фронт говорит "ок", а в базе запись как сидела, так и сидит, хитрая жопа.
  • Как сервисы друг друга ебут: Интеграционное тестирование, короче. Чтобы один микросервис другому не гнал такую дичь, от чего тот накрывался медным тазом.
  • А выдержит ли?: Нагрузочное тестирование. Ты на API наваливаешь овердохуища запросов и смотришь, не ляжет ли он, бедолага, и не начнёт ли тебе вместо JSON'а матерные одностишья слать.

Ну а фронтенд (оставшиеся 30%, чтоб не скучал):

  • Критичная логика, завязанная на бэк: Отправил форму — пришёл ответ. Упала ошибка — показалось адекватное сообщение, а не [object Object]. Всё, что требует похода на сервер.
  • Валидация на стороне клиента: Ну, чтоб сразу юзеру было понятно, что почту "petya@sobaka" вводить не надо.
  • Базовый UI: Чтоб в хроме кнопка была кнопкой, а в фаерфоксе не превращалась в пиздопроебибну. И чтоб по макетам было, а не "я так вижу".

Вот тебе пример, как мы бэкенд мучаем (создание пользователя):

import requests

def test_user_creation_api():
    """Тестирует эндпоинт создания нового пользователя."""
    url = "https://api.example.com/v1/users"
    payload = {
        "name": "John Doe",
        "email": "john.doe@example.com"
    }
    headers = {"Content-Type": "application/json"}

    response = requests.post(url, json=payload, headers=headers)

    # Проверяем успешный ответ
    assert response.status_code == 201
    response_data = response.json()
    assert "id" in response_data
    assert isinstance(response_data["id"], str)
    assert response_data["name"] == payload["name"]
    assert response_data["email"] == payload["email"]

    # (Дополнительно) Проверяем, что пользователь появился в БД
    # db_check_user_exists(response_data["id"]) ...

А фронтенд-тесты потом будут как раз вокруг этого API вертеться: нажал кнопку "Создать" — этот запрос ушёл? Ответ пришёл? Ошибку красиво показало? Вот и вся ихняя, блядь, работа, если честно.