测试 方法论
137 个端到端测试验证每个生成的 SQL 查询与 Prisma 输出完全一致
如何验证正确性
每个测试都遵循严格的 5 步验证流程,以确保生成的 SQL 产生与 Prisma 相同的结果
从 Prisma 查询生成 SQL
解析 Prisma 查询参数并使用相同的模型和 schema 生成等效 SQL。生成的 SQL 使用参数化查询以确保安全性和性能。
并行执行两个查询
通过 postgres.js 或 better-sqlite3 直接运行生成的 SQL,并通过 Prisma 执行相同的查询。两者都针对相同的数据库状态。
标准化结果
处理类型差异(BigInt vs Number、Decimal 精度、Date 序列化)并标准化对象键顺序以便公平比较。
深度相等性检查
验证结果完全匹配:相同的行数、相同的字段值、相同的嵌套关系、相同的顺序。任何不匹配都会导致测试失败。
性能基准测试
使用 5 次预热运行测量执行时间,然后对每个测试平均 10-50 次迭代。与 Prisma v6、Prisma v7 和 Drizzle ORM 进行比较。
高级验证技术
数据类型标准化
- • BigInt 转换: JavaScript BigInt → Number 用于比较
- • Decimal 处理: Prisma Decimal → 10 位精度的 Float
- • 日期标准化: 所有 DateTime 值 → null(专注于数据,而非时间戳)
- • JSON 解析: 自动检测和解析 JSON 字符串
- • 对象键排序: 按字母顺序排序以确保一致比较
性能基准测试
- • 预热阶段: 5 次迭代以预热缓存和 JIT
- • 自适应迭代: 根据查询复杂度进行 5-50 次运行
- • 隔离测量: 每种查询类型独立测量
- • 多 ORM 对比: Prisma v6、v7、Drizzle、Generated SQL
- • SQL 生成时间: 单独计时查询生成开销
全面的测试覆盖
测试涵盖跨多个复杂级别的每个 Prisma 读取操作
查询操作
- 带复杂过滤器的 findMany
- 带 skip 和分页的 findFirst
- 通过 ID 和唯一字段的 findUnique
- 带 WHERE 条件的 count
- 聚合(sum、avg、min、max)
- 带 HAVING 子句的 groupBy
复杂场景
- 嵌套 includes(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 时间戳。