Что такое State Transition Testing (тестирование переходов состояний)?

Ответ

State Transition Testing — это техника тест-дизайна, которая фокусируется на проверке корректности переходов системы между различными состояниями в ответ на события или входные данные. Она особенно полезна для систем с конечным числом состояний (finite-state machines), где результат зависит от истории предыдущих действий.

Основная идея: система может находиться в определенном состоянии (State), и событие (Event) переводит ее в другое состояние, возможно, с каким-то действием (Action). Тестирование проверяет как валидные, так и невалидные переходы.

Пример для банкомата:

  1. Состояние: Карта вставленаСобытие: Ввод корректного PINНовое состояние: Доступ разрешен.
  2. Состояние: Карта вставленаСобытие: Ввод неверного PIN 3 разаНовое состояние: Карта заблокирована.

Пример тест-кейса на Python:

class LoginSystem:
    def __init__(self):
        self.state = "LOGGED_OUT"
        self.attempts = 0

    def enter_password(self, pwd):
        if pwd == "correct":
            self.state = "LOGGED_IN"
        else:
            self.attempts += 1
            if self.attempts >= 3:
                self.state = "LOCKED"

def test_state_transition_to_locked():
    system = LoginSystem()
    # Три неверные попытки
    for _ in range(3):
        system.enter_password("wrong")
    assert system.state == "LOCKED"

Когда применять: тестирование workflow (заказ товара, процесс одобрения), логики авторизации, бизнес-процессов с четкими этапами.

Ответ 18+ 🔞

Да ты посмотри, что вытворяют эти тестировщики! Сидят, блядь, и думают, как бы нам ещё одну хитрую хуйню придумать, чтобы разработчикам мозг выебать. А оказывается, идея-то, ёпта, гениальная в своей простоте, как хуй с горы — виден издалека и всем понятен.

Вот смотри, есть у нас система. Она не просто тупо стоит, как пень, а живёт своей жизнью, перетекает из одного состояния в другое. Как пьяный мужик в подъезде: сначала состояние «Ищу ключи», потом событие «Ключи не лезут» — и новое состояние «Бью ногой по двери». А потом действие «Приехали менты» и переход в состояние «Еду в обезьянник». Понимаешь? Вся история важна!

Основная мысль, блядь: у системы есть состояние (State), на неё прилетает событие (Event), она делает действие (Action) и переходит в новое состояние. А мы, как хитрая жопа, должны проверить, что она не свалится в состояние «Наебнулась» от какого-нибудь левого пинка.

Возьмём банкомат, классика жанра:

  1. Состояние: Карта воткнута. Событие: Ввели правильный пин. Новое состояние: Можно грабить корованы (ну, Доступ разрешён).
  2. Состояние: Карта воткнута. Событие: Три раза ввели хуйню. Новое состояние: Карта — кирпич, иди нахуй (Карта заблокирована).

А теперь смотри, как это выглядит в коде, если бы его писал наш Герасим, который только «Муму» говорить умеет, но зато в Python’е шарит.

class LoginSystem:
    def __init__(self):
        self.state = "LOGGED_OUT"  # Начальное состояние — всех послал
        self.attempts = 0

    def enter_password(self, pwd):
        if pwd == "correct":  # Угадал, молодец
            self.state = "LOGGED_IN"
        else:
            self.attempts += 1  # Ошибся, сука, считаем
            if self.attempts >= 3:  # Три раза накосячил? Всё, пиздец.
                self.state = "LOCKED"

def test_state_transition_to_locked():
    system = LoginSystem()
    # Три раза тыкаем как баран в неправильный пароль
    for _ in range(3):
        system.enter_password("wrong")
    # И теперь проверяем, что система в состоянии «Иди нахуй, заблокирован»
    assert system.state == "LOCKED"

Когда эту хуйню применять? Да когда угодно, где есть какой-то процесс! Заказ пиццы (выбрал → оплатил → готовится → едет → в жопе), одобрение отпуска (подал → на столе у начальника → в корзине → снова подай), да та же авторизация. Всё, где система помнит, что было «вчера», и от этого зависит, что будет «сегодня». А то без этого подхода она как мартышлюшка: нажал на кнопку — получил результат, а что было до этого — ни хуя не помнит. Так не пойдёт.