На основании чего вы определяете ожидаемый результат (expected behavior) при тестировании?

Ответ

Ожидаемое поведение системы определяется из иерархии источников, где приоритет отдается явным и формальным требованиям:

Источники в порядке приоритета:

  1. Явные требования: Функциональные спецификации (SRS), User Stories с критериями приемки (Acceptance Criteria), техническое задание (ТЗ).
  2. Техническая документация: Документация API (OpenAPI/Swagger), руководства пользователя, интерфейсные гайдлайны.
  3. Стандарты и протоколы: RFC для сетевых взаимодействий, отраслевые стандарты (например, PCI DSS для платежных систем).
  4. Общепринятые практики (Best Practices) и здравый смысл: Логичные UX-паттерны (например, сообщение об успешном сохранении), принципы работы с данными (идемпотентность методов PUT).

Процесс уточнения: Если информация в источниках 1-3 отсутствует или противоречива, я согласовываю ожидания с ответственными сторонами — продукт-менеджером, бизнес-аналитиком или lead-разработчиком. Это критически важно для избежания разночтений.

Пример: Определение ожидания для простой функции

# Тест для функции сложения. Ожидание основано на базовой математике (источник #4).
def test_addition():
    """
    Ожидаемое поведение: Функция add() должна возвращать
    математическую сумму двух чисел.
    Источник ожидания: Общеизвестный математический принцип.
    """
    result = add(2, 2)
    # Ожидаемый результат — 4
    assert result == 4, f"Ожидалось, что 2 + 2 = 4, но функция вернула {result}"

    # Дополнительные проверки на основе здравого смысла:
    assert add(0, 5) == 5  # Ноль не должен менять сумму
    assert add(-1, 1) == 0 # Сумма противоположных чисел равна нулю

Четкая привязка ожиданий к конкретному источнику позволяет обосновать тестовый сценарий и упрощает коммуникацию в случае обнаружения расхождений.

Ответ 18+ 🔞

Ага, слушай, вот эта вся хуйня с ожиданиями в тестах — это ж, блядь, целая наука, а не просто так, на глазок. Сейчас разложу, как у нормальных людей это делается, а не как у мартышлюшек, которые потом орут: «А я думал, тут должно быть так!».

Смотри, у нас тут, как в хорошем детективе, есть своя иерархия улик, прости, источников. И приоритет у них разный, ёпта.

Откуда, сука, мы вообще знаем, что система должна делать? Вот порядок, от самого важного до «ну, наверное»:

  1. Явные требования: Это святое, блядь. Если есть SRS, User Stories с этими самыми Acceptance Criteria или, не дай бог, техническое задание (ТЗ) — ты сначала туда смотришь. Это как прямой приказ.
  2. Техническая документация: Ну, тут уже попроще. Документация к API (этот твой Swagger), мануалы для пользователей, гайдлайны по интерфейсу. Если в первом пункте не прописано, лезем сюда.
  3. Стандарты и протоколы: Это уже для продвинутых. RFC для сетевого общения, всякие PCI DSS для платёжек. Система должна им соответствовать, и точка.
  4. Здравый смысл и общепринятые практики: А вот это, блядь, самая скользкая хуйня. Логичный UX (например, после сохранения показывать «Успешно»), идемпотентность PUT-методов. Используется, когда вышестоящие источники молчат, как рыбы об лёд.

А что, если нихуя не понятно или везде написано разное? Вот тут-то и начинается цирк. Ни в коем случае не начинай гадать, какой из двух противоречивых пунктов «более правильный». Это путь в ад, чувак. Надо иди и согласуй с ответственными. С продукт-менеджером, аналитиком или тимлидом. Спроси: «Мужики, тут пиздец, разберитесь». Иначе потом окажется, что ты полгода тестировал не ту фичу, и волнение ебать.

Ну и пример, чтобы совсем доходило, как это работает на практике:

# Тестируем функцию сложения. Ожидание — откуда? Из головы? Не-е-ет.
def test_addition():
    """
    Ожидаемое поведение: Функция add() должна возвращать
    математическую сумму двух чисел.
    Источник ожидания: Общеизвестный математический принцип (тот самый наш "здравый смысл", пункт №4).
    Потому что в ТЗ про сложение 2+2 нихуя не написано, это и ежу понятно.
    """
    result = add(2, 2)
    # Ожидаемый результат — 4, и это не я придумал, это Архимед, блядь, ещё до нашей эры.
    assert result == 4, f"Ожидалось, что 2 + 2 = 4, но функция вернула {result}. Ты чё, совсем, блядь?"

    # А это уже дополнительные проверки на основе того же здравого смысла:
    assert add(0, 5) == 5  # Ноль — он и в Африке ноль, сумму не меняет.
    assert add(-1, 1) == 0 # Минус один и один — ноль. Базовая математика, ёпта!

Вот когда у каждого твоего assert есть вот такой вот «источник истины», тебе уже не придётся в споре с разработчиком орать: «Ну я так чувствую!». Ты скажешь: «Смотри, дружок-пирожок, в спецификации на странице 45, пункт 3.14, чёрным по белому написано, что кнопка должна быть зелёной. А у тебя — красная, пидарас шерстяной». И всё, приехали. Коммуникация на уровне, а не на уровне «да похуй».