Как вы определяете ожидаемое поведение программы (software) для составления тест-кейсов?

Ответ

Определение ожидаемого поведения программы — это процесс анализа нескольких взаимодополняющих источников информации для формирования однозначных и проверяемых критериев.

Основные источники и их роль: Источник Что дает Пример использования в тестах
Требования (SRS, User Stories) Формальное описание что должна делать система. Основы для happy path и основных функциональных тестов.
Документация (API Docs, мануалы) Технические детали как система это делает. Тестирование граничных значений, форматов запросов/ответов.
Стандарты и Best Practices Отраслевые нормы и соглашения. Тесты на безопасность, доступность, производительность.
Аналогичные системы Референсное поведение. Формирование гипотез при отсутствии других источников.
Коммуникация с командой Уточнение неявных требований. Разрешение противоречий, прояснение бизнес-логики.

Процесс на практике:

  1. Сбор данных из доступных источников.
  2. Анализ на противоречия и неоднозначности.
  3. Уточнение спорных моментов у аналитиков или разработчиков.
  4. Формализация в виде четких, проверяемых утверждений (assertions).

Пример: Тестирование сценария логина

import requests
# Ожидаемое поведение основано на требованиях (редирект) и best practices (безопасность).
def test_successful_login_flow():
    """
    Ожидаемое поведение после успешного ввода учетных данных:
    1. HTTP-статус 302 (Found) для перенаправления. (Из требований)
    2. Заголовок Location указывает на страницу /dashboard. (Из требований)
    3. В ответе установлен cookie сессии. (Best practice для аутентификации)
    4. Сам cookie помечен как HttpOnly и Secure. (Best practice безопасности)
    """
    login_url = "https://app.example.com/login"
    credentials = {"username": "valid_user", "password": "correct_password"}

    # Отправляем запрос, отключив автоматическое следование редиректу
    response = requests.post(login_url, data=credentials, allow_redirects=False)

    # 1. Проверка редиректа
    assert response.status_code == 302, "После успешного логина должен быть редирект (302)"

    # 2. Проверка цели редиректа
    redirect_location = response.headers.get("Location")
    assert redirect_location == "/dashboard", f"Ожидался редирект на /dashboard, а не на {redirect_location}"

    # 3. Проверка наличия cookie сессии
    session_cookie = response.cookies.get("session_id")
    assert session_cookie is not None, "В ответе должен быть установлен cookie сессии"

    # 4. Проверка атрибутов безопасности cookie (на примере объекта response.cookies)
    # Примечание: Детальная проверка флагов может требовать анализа raw-заголовков.
    print(f"Cookie session_id установлен: {session_cookie}")
    # Дальнейшие проверки безопасности лучше проводить через анализ заголовков Set-Cookie

Для UI-тестов эталоном часто служат утвержденные макеты дизайна (UI mockups). В случае выявления расхождения между поведением программы и ожиданиями, создается баг-репорт, который служит точкой для обсуждения и уточнения требований.

Ответ 18+ 🔞

Да ты посмотри, что за науку из тестирования развели! Ожидаемое поведение, блядь... А по-простому — какого хуя программа должна делать, чтобы не обосраться при всех.

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

Откуда ноги растут, или где искать правду-матку:

  • Требования (эти ваши SRS, User Stories). Это типа священное писание, что должно работать. Если там написано «кнопка делает ХУЙ», а она делает ПИЗДУ — это баг, а не фича. Основа для всех этих счастливых путей.
  • Документация (API Docs, мануалы). А это уже техническая подноготная — как именно эта хуйня должна работать. Какой формат запроса, какой ответ, какие коды. Без этого — ты слепой крот, который будет наугад API долбить.
  • Стандарты и Best Practices. Это типа неписаные законы улицы. Если ты делаешь авторизацию, а куки без флагов HttpOnly и Secure — ты просто пидарас, и тебя надо мочить. Тестировщик должен это знать и проверять, даже если в требованиях про это ни хуя не сказано.
  • Похожие системы. Когда от заказчика приходит ТЗ на пол-листа А4, а от него пахнет самогоном — смотри, как эту же хуйню сделали другие. Чтобы хотя бы гипотезы строить, а не пальцем в небо тыкать.
  • Общение с командой. А вот это, сука, самый главный источник! Потому что обычно требования написаны кривыми руками пьяного аналитика, а разработчик сделал «как лучше». И вот ты сидишь, ебёшь мозг, и думаешь — это баг или фича? Идешь и спрашиваешь. Иначе так и будешь сидеть, как Герасим немой, и мычать «Му-му», блядь.

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

  1. Собери всё, что есть. Все бумажки, все ссылки, все скриншоты, все переписки в Slack, где тимлид сказал «да, это так должно быть».
  2. Найди противоречия. Вот тут-то и начинается пиздец и веселье. Обычно в двух документах про одну и ту же кнопку написано прямо противоположное. Удивление пиздец!
  3. Иди и уточняй. Не стесняйся. Лучше выглядеть идиотом пять минут, чем потом месяц доказывать, что баг — это не баг, а «особенность реализации».
  4. Зафиксируй, как отче наш. Преврати эту всю хуйню в четкие, проверяемые утверждения. Не «должно работать», а «при вводе валидных данных пользователь попадает на страницу /dashboard, получает куку session_id с флагами HttpOnly и Secure, а HTTP-статус — 302».

Вот, смотри, живой пример, как это в коде выглядит:

import requests

def test_successful_login_flow():
    """
    Чего мы ждем после того, как юзер ввел логин-пароль и нажал "Войти":
    1. Сервер говорит: "Иди нахуй отсюда" статусом 302 (редирект). (Из требований)
    2. И указывает пальцем: "Иди вот на страницу /dashboard". (Тоже из требований)
    3. И сует тебе в руки пропуск — куку сессии. (Best practice, ёпта!)
    4. И этот пропуск должен быть с защитой от копирования (HttpOnly и Secure). (Best practice безопасности, иначе ты пидарас)
    """
    login_url = "https://app.example.com/login"
    credentials = {"username": "valid_user", "password": "correct_password"}

    # Шлем запрос, но говорим "не ходи за редиректом сам, я сам проверю"
    response = requests.post(login_url, data=credentials, allow_redirects=False)

    # 1. Проверяем, послал ли нас сервер нахуй (редирект 302)
    assert response.status_code == 302, "Бля, после логина должен быть редирект 302, а не это вот всё!"

    # 2. Проверяем, куда именно нас послали
    redirect_location = response.headers.get("Location")
    assert redirect_location == "/dashboard", f"Ожидали редирект на /dashboard, а нас послали на {redirect_location}!"

    # 3. Проверяем, дали ли нам пропуск (куку)
    session_cookie = response.cookies.get("session_id")
    assert session_cookie is not None, "Какого хуя? Куку сессии не выдали! Без пропуска не пустят!"

    # 4. Проверка безопасности куки — это уже тоньше, часто надо в заголовки Set-Cookie лезть
    print(f"Кука session_id получена: {session_cookie}")
    # Дальше можно парсить заголовок Set-Cookie и смотреть, есть ли там священные флаги HttpOnly и Secure.

Для интерфейсов твоим священным граалем будут утвержденные макеты (UI mockups). Если кнопка на макете синяя, а в жизни — зеленая в горошек, это повод орать.

А если вдруг выяснилось, что программа делает не то, что все ожидали — поздравляю, ты нашел баг. Пиши баг-репорт. Это и есть та самая бумажка, с которой ты идешь к разработчикам и аналитикам и начинаешь великий спор: «Это баг или фича?». И вот тут-то и рождается истинное, ёбта, ожидаемое поведение.