Ответ
Тестирование БД включает несколько критически важных слоёв:
1. Тестирование схемы (Structure Testing):
-- Проверка целостности схемы
SELECT
table_name,
column_name,
data_type,
is_nullable,
column_default
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;
-- Проверка индексов
SELECT
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname = 'public';
2. Тестирование ограничений (Constraint Testing):
- NOT NULL – попытка вставки NULL в обязательные поля
- UNIQUE – проверка на дубликаты
- FOREIGN KEY – каскадные операции и ссылочная целостность
- CHECK – валидация бизнес-правил на уровне БД
3. Тестирование миграций:
# Пример теста миграции с Alembic
from alembic import command
from alembic.config import Config
def test_migration_up_down():
alembic_cfg = Config("alembic.ini")
# Применяем миграцию
command.upgrade(alembic_cfg, "head")
# Проверяем, что таблица создалась
with engine.connect() as conn:
result = conn.execute("SELECT EXISTS (SELECT FROM new_table)")
assert result.scalar() is True
# Откатываем миграцию
command.downgrade(alembic_cfg, "-1")
4. Тестирование производительности:
- EXPLAIN ANALYZE для анализа планов запросов
- Тестирование на больших объемах данных (100K+ записей)
- Проверка блокировок и deadlock'ов при конкурентном доступе
5. Тестирование резервного копирования:
- Восстановление из backup на тестовом окружении
- Проверка целостности данных после восстановления
- Тестирование point-in-time recovery
6. Интеграционные тесты:
@pytest.fixture
def test_db():
# Создание изолированной тестовой БД
engine = create_engine(TEST_DATABASE_URL)
Base.metadata.create_all(engine)
return engine
def test_transaction_rollback(test_db):
with test_db.begin() as conn:
conn.execute("INSERT INTO users (name) VALUES ('test')")
# Явный откат
raise Exception("Force rollback")
# Проверяем, что данные не сохранились
result = test_db.execute("SELECT COUNT(*) FROM users")
assert result.scalar() == 0