Методология тестирования
137 сквозных тестов проверяют, что каждый SQL-запрос точно совпадает с выводом Prisma
Как мы проверяем корректность
Каждый тест проходит строгий 5-этапный процесс валидации, чтобы убедиться, что сгенерированный SQL даёт идентичные результаты Prisma
Генерация SQL из запроса Prisma
Парсинг аргументов Prisma и генерация эквивалентного SQL на основе тех же моделей и схемы. Сгенерированный SQL использует параметризованные запросы для безопасности и производительности.
Параллельное выполнение обоих запросов
Выполнение сгенерированного SQL напрямую через postgres.js или better-sqlite3 и выполнение того же запроса через Prisma. Оба запроса работают с одним состоянием базы.
Нормализация результатов
Обработка различий типов (BigInt vs Number, точность Decimal, сериализация Date) и нормализация порядка ключей объектов для честного сравнения.
Глубокая проверка равенства
Проверка точного совпадения: одинаковое количество строк, те же значения полей, те же вложенные связи, тот же порядок. Любое несовпадение приводит к провалу теста.
Бенчмарк производительности
Измерение времени выполнения с 5 разогревочными запусками, затем усреднение 10-50 итераций на тест. Сравнение с Prisma v6, Prisma v7 и Drizzle ORM.
Продвинутые техники валидации
Нормализация типов данных
- • Конвертация BigInt: JavaScript BigInt → Number для сравнения
- • Обработка Decimal: Prisma Decimal → Float с точностью 10 знаков
- • Нормализация дат: Все DateTime значения → null (фокус на данных, не на временных метках)
- • Парсинг JSON: Автоматическое определение и парсинг JSON строк
- • Сортировка ключей объектов: Алфавитный порядок для консистентного сравнения
Бенчмаркинг производительности
- • Фаза разогрева: 5 итераций для прогрева кэшей и JIT
- • Адаптивные итерации: 5-50 запусков в зависимости от сложности запроса
- • Изолированное измерение: Каждый тип запроса измеряется независимо
- • Сравнение нескольких ORM: Prisma v6, v7, Drizzle, Generated SQL
- • Время генерации SQL: Отдельный замер накладных расходов генерации запросов
Полное покрытие тестами
Тесты покрывают все операции чтения Prisma на разных уровнях сложности
Операции запросов
- findMany со сложными фильтрами
- findFirst с skip и пагинацией
- findUnique по ID и уникальным полям
- count с условиями WHERE
- aggregate (sum, avg, min, max)
- groupBy с условиями HAVING
Сложные сценарии
- Вложенные include (4 уровня)
- Фильтры связей (some/every/none)
- Distinct с оконными функциями
- Курсорная пагинация
- Select + include вместе
- Подсчёт связей (_count)
Типы фильтров
- Сравнения (lt/lte/gt/gte)
- Логические (AND/OR/NOT)
- Строковые операции (contains/startsWith)
- Проверка NULL (is/isNot)
- IN/NOT IN массивы
- Режимы регистра
Тестирование PostgreSQL
- ✓ ILIKE регистронезависимый поиск
- ✓ Операции с JSON/JSONB
- ✓ Обработка массивов
- ✓ Поддержка составных типов
- ✓ Валидация оконных функций
- ✓ Тестирование изоляции транзакций
Тестирование SQLite
- ✓ LIKE сопоставление паттернов
- ✓ Валидация расширения JSON1
- ✓ Эмуляция оконных функций
- ✓ Оптимизация DISTINCT
- ✓ Корреляция подзапросов
- ✓ Обработка текстовой аффинности
Пример тестового случая
Как мы проверяем сложный вложенный запрос с фильтрами связей
it('nested relation filter', () =>
runParityTest(
db,
benchmarkResults,
'findMany nested relation',
'Organization',
{
method: 'findMany',
where: {
projects: {
some: {
tasks: { some: { status: 'DONE' } }
}
}
}
},
() => db.prisma.organization.findMany({
where: {
projects: {
some: {
tasks: { some: { status: 'DONE' } }
}
}
},
orderBy: { id: 'asc' }
}),
)
)
// runParityTest внутри:
// 1. Вызывает generateSQL() с аргументами
// 2. Выполняет сгенерированный SQL напрямую
// 3. Выполняет запрос Prisma
// 4. Нормализует оба результата
// 5. Глубокая проверка равенства - падает при любом различии
// 6. Бенчмарк времени выполнения Что происходит при выполнении теста
1. Генерация запроса (микросекунды)
Функция generateSQL() парсит аргументы Prisma и создаёт параметризованный SQL. Этот шаг измеряется отдельно для оценки накладных расходов генерации.
2. Параллельное выполнение (миллисекунды)
Оба запроса обращаются к одному состоянию БД одновременно через Promise.all(), обеспечивая честное сравнение и идентичные условия данных.
3. Глубокая нормализация
Результаты проходят рекурсивную нормализацию: BigInt→Number, Decimal→Float(10), Date→null, парсинг JSON, сортировка ключей. Это гарантирует побайтовую точность сравнения.
4. Строгое равенство
Сравнение через JSON stringify с нулевой толерантностью. Любое несовпадение в количестве строк, значениях полей, вложенных объектах или порядке приводит к провалу теста с детальным выводом различий.
5. Измерение производительности
После валидации 5-50 итераций измеряют среднее время выполнения. Результаты включают: Prisma v6, Prisma v7, Drizzle ORM, Generated SQL и накладные расходы генерации SQL.
Мультиверсионная валидация
Каждый тест запускается как с Prisma v6, так и с v7 для гарантии совместимости между версиями:
Prisma v6 (6.16.3)
- • Прямое использование PrismaClient
- • Устаревшая архитектура движка
- • Базовые метрики производительности
Prisma v7 (7.2.0)
- • Архитектура на основе адаптеров
- • @prisma/adapter-pg и adapter-better-sqlite3
- • Новые оптимизации движка
Автоматические отчёты бенчмарков
Все результаты бенчмарков автоматически генерируются и сохраняются в JSON файлы для полной прозрачности:
benchmark-results/v6-postgres-latest.json benchmark-results/v7-postgres-latest.json benchmark-results/v6-sqlite-latest.json benchmark-results/v7-sqlite-latest.json Каждый файл содержит: название теста, время выполнения Prisma, время генерации SQL, время Drizzle, коэффициенты ускорения и ISO временную метку.
Изучите полный набор тестов
Все 137 тестов с открытым исходным кодом. Просмотрите тестовый код, бенчмарки и логику валидации.