Опишите сложный баг, с которым вы столкнулись, и как вы его исследовали и устраняли.

«Опишите сложный баг, с которым вы столкнулись, и как вы его исследовали и устраняли.» — вопрос из категории Основы тестирования, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сложный баг: Race Condition (состояние гонки) при параллельном обновлении баланса пользователя через API.

Проблема: При быстрых последовательных запросах на пополнение счета (например, два одновременных запроса на +50 и +30 к балансу 100) итоговый баланс мог стать 130 или 150, вместо корректных 180. Данные терялись.

Исследование и воспроизведение:

  1. Анализ: Изучение логики кода показало уязвимость: баланс = прочитать_из_БД(); баланс += сумма; сохранить_в_БД(баланс).
  2. Воспроизведение: Создание скрипта для имитации параллельных запросов.
    
    import concurrent.futures
    import requests

Функция для пополнения баланса

def add_funds(user_id, amount): response = requests.post( f"https://api.example.com/users/{user_id}/balance", json={"action": "add", "amount": amount} ) return response.json()

Запуск 10 параллельных запросов

user_id = "user123" with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: futures = [executor.submit(add_funds, userid, 10) for in range(10)] results = [f.result() for f in futures]

Проверка итогового баланса - может быть меньше 100 (стартовый 0 + 10*10)

final_balance = requests.get(f"https://api.example.com/users/{user_id}/balance").json() print(f"Итоговый баланс: {final_balance}") # Может быть 60, 70 и т.д.


3.  **Логирование:** Добавление детального логирования (ID запроса, баланс до/после) помогло увидеть "наложение" операций.

**Причина и решение:**
*   **Причина:** Отсутствие механизма блокировки или атомарности операций на уровне БД.
*   **Решение:**
    1.  **Оптимальное:** Изменить логику на атомарную операцию БД: `UPDATE balance SET value = value + :amount WHERE user_id = :id`.
    2.  **Альтернативное:** Внедрить **оптимистичную блокировку** (проверка версии записи) или **пессимистичную блокировку** (SELECT FOR UPDATE) на уровне приложения.

**Итог:** Баг был исправлен переходом на атомарный SQL-запрос. Это подчеркивает важность тестирования многопоточных сценариев и понимания работы с данными в конкурентной среде.