🧪 质量保证

测试 方法论

137 个端到端测试验证每个生成的 SQL 查询与 Prisma 输出完全一致

137
端到端测试
每个查询均已验证
100%
完全对等
逐字节匹配
2
数据库引擎
PostgreSQL 与 SQLite
3
ORM 基准测试
Prisma v6/v7、Drizzle

如何验证正确性

每个测试都遵循严格的 5 步验证流程,以确保生成的 SQL 产生与 Prisma 相同的结果

1

从 Prisma 查询生成 SQL

解析 Prisma 查询参数并使用相同的模型和 schema 生成等效 SQL。生成的 SQL 使用参数化查询以确保安全性和性能。

2

并行执行两个查询

通过 postgres.js 或 better-sqlite3 直接运行生成的 SQL,并通过 Prisma 执行相同的查询。两者都针对相同的数据库状态。

3

标准化结果

处理类型差异(BigInt vs Number、Decimal 精度、Date 序列化)并标准化对象键顺序以便公平比较。

4

深度相等性检查

验证结果完全匹配:相同的行数、相同的字段值、相同的嵌套关系、相同的顺序。任何不匹配都会导致测试失败。

5

性能基准测试

使用 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 优化
  • ✓ 子查询关联
  • ✓ 文本亲和性处理

示例测试用例

查看我们如何验证带关系过滤器的复杂嵌套查询

tests/e2e/postgres.test.ts
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 个测试都是开源的。查看测试代码、基准测试和验证逻辑。