← Назад к вопросам

Как изменял данные в базе данных на проекте

1.3 Junior🔥 171 комментариев
#Инструменты тестирования#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подход к модификации данных в БД в тестировании

Изменение данных в базе данных — это стандартная и необходимая практика в работе QA-инженера для подготовки тестовых сценариев, воспроизведения дефектов и очистки окружения. На проектах я использовал различные методы и инструменты в зависимости от контекста, требований безопасности и стабильности.

Основные методы изменения данных в БД

  1. Прямое выполнение SQL-запросов (наиболее частый способ для подготовки данных):
    *   Использовался на этапах **разработки и тестирования** для быстрого создания специфичных состояний системы.
    *   **Инструменты:** DBeaver, pgAdmin, MySQL Workbench, IntelliJ IDEA Database Console, командная строка (`psql`, `mysql`).
    *   Пример создания тестового заказа с определённым статусом:
```sql
-- Вставка тестового пользователя (если отсутствует)
INSERT INTO users (id, username, email, status)
VALUES (99999, 'test_user', 'test@example.com', 'ACTIVE')
ON CONFLICT (id) DO NOTHING;

-- Создание заказа в статусе 'PENDING_PAYMENT' для проверки процесса оплаты
INSERT INTO orders (id, user_id, amount, status, created_at)
VALUES (88888, 99999, 150.75, 'PENDING_PAYMENT', NOW());
```

2. Использование миграций (Liquibase, Flyway):

    *   Для применения структурных изменений и эталонных данных (reference data) на всех окружениях единообразно.
    *   Позволяет версионировать изменения и быть уверенным, что на всех стендах одинаковая схема БД.
    *   Пример скрипта Flyway для добавления нового справочного значения:
```sql
-- V20241217_1101__add_new_payment_status.sql
INSERT INTO payment_status (code, description)
VALUES ('AWAITING_3DS', 'Ожидание подтверждения 3-D Secure');
```

3. Интеграционные и E2E-тесты через API/UI:

    *   **Основной предпочтительный метод** для сквозного тестирования. Данные создаются через публичный интерфейс системы (API или веб-интерфейс), что гарантирует прохождение всей бизнес-логики и валидации.
    *   Прямые манипуляции с БД в этом случае используются только для проверки результатов или для подготовки невозможных через API состояний (например, "сломанные" данные для негативных тестов).
```python
# Пример подготовки данных через API в автотесте (Python + pytest/requests)
def create_user_for_test(user_data):
    response = requests.post(f"{BASE_API_URL}/users", json=user_data, headers=AUTH_HEADERS)
    response.raise_for_status()
    return response.json()  # Возвращаем созданный объект, например, с ID

@pytest.fixture
def test_order(create_user_for_test):
    user = create_user_for_test({"username": "autotest_user"})
    order_payload = {"userId": user["id"], "items": [{"productId": 5, "qty": 2}]}
    order_response = requests.post(f"{BASE_API_URL}/orders", json=order_payload, headers=AUTH_HEADERS)
    return order_response.json()
```

4. Скрипты (Python/Bash) и утилиты командной строки:

    *   Для массовых или регулярных операций: очистка старых тестовых данных, накат фикстур, синхронизация данных между средами.
```bash
# Пример bash-скрипта для очистки тестовых данных, созданных более суток назад
psql $DATABASE_URL -c "DELETE FROM sessions WHERE created_at < NOW() - INTERVAL '1 day';"
```

Ключевые принципы и меры предосторожности

  • Чёткое разделение окружений: Прямые манипуляции допустимы только на тестовых и development-окружениях. Никаких прямых запросов к staging или production без исключительной необходимости, санкционированных изменений (change request) и под контролем DBA/дежурного инженера.
  • Транзакционность и откат изменений: Все операции вручную выполнял в явных транзакциях (BEGIN; ... ROLLBACK/COMMIT;), сначала проверяя результат запросом SELECT. В автотестах использовал механизмы отката (трамплинные таблицы, аннотации @Transactional в Spring, фикстуры в pytest с очисткой после каждого теста).
  • Резервное копирование (бекап): Перед выполнением деструктивных операций (UPDATE, DELETE на больших таблицах) или сложных миграций всегда удостоверялся в наличии свежего бекапа или экспортировал затрагиваемые данные.
  • Документирование: Сложные или неочевидные запросы для подготовки данных фиксировал в команде (в wiki, README тестового репозитория) для коллег.
  • Использование тестовых данных: Всегда использовал данные, которые явно идентифицируются как тестовые (префиксы test_, специальные email-адреса @example.com, флаги is_test = true), чтобы их можно было безопасно найти и удалить.

Пример реального сценария

Для тестирования функционала "Отмена заказа с истёкшим сроком оплаты" мне нужно было создать заказ, у которого status = 'PENDING_PAYMENT', а created_at — более 20 минут назад (срок оплаты по бизнес-правилам).

  1. Через API создать заказ в статусе PENDING_PAYMENT нельзя — система сразу переводит его в NEW.
  2. Решение: Создать заказ через API, затем прямым безопасным запросом в БД изменить его статус и время создания.
    BEGIN;
    -- Предварительно получаем ID только что созданного через API заказа
    SELECT id FROM orders WHERE user_id = 99999 ORDER BY id DESC LIMIT 1;
    
    -- Изменяем данные (предположим, ID = 100500)
    UPDATE orders
    SET status = 'PENDING_PAYMENT',
        created_at = NOW() - INTERVAL '25 minutes'
    WHERE id = 100500;
    -- Проверяем
    SELECT id, status, created_at FROM orders WHERE id = 100500;
    COMMIT;
    
  3. После этого запускал E2E-тест, который проверял, что система автоматически переводит такой заказ в статус CANCELLED.

Таким образом, грамотное сочетание методов (API для легитимных сценариев и контролируемое прямое изменение БД для специфичных или негативных кейсов) позволяет эффективно покрывать тестами сложную бизнес-логику, сохраняя при этом целостность данных и стабильность тестового окружения.

Как изменял данные в базе данных на проекте | PrepBro