Как изменял данные в базе данных на проекте
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Подход к модификации данных в БД в тестировании
Изменение данных в базе данных — это стандартная и необходимая практика в работе QA-инженера для подготовки тестовых сценариев, воспроизведения дефектов и очистки окружения. На проектах я использовал различные методы и инструменты в зависимости от контекста, требований безопасности и стабильности.
Основные методы изменения данных в БД
- Прямое выполнение 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 минут назад (срок оплаты по бизнес-правилам).
- Через API создать заказ в статусе
PENDING_PAYMENTнельзя — система сразу переводит его вNEW. - Решение: Создать заказ через 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; - После этого запускал E2E-тест, который проверял, что система автоматически переводит такой заказ в статус
CANCELLED.
Таким образом, грамотное сочетание методов (API для легитимных сценариев и контролируемое прямое изменение БД для специфичных или негативных кейсов) позволяет эффективно покрывать тестами сложную бизнес-логику, сохраняя при этом целостность данных и стабильность тестового окружения.