🧪 Assurance qualité

Tests Méthodologie

137 tests end-to-end valident que chaque requête SQL générée correspond exactement à la sortie de Prisma

137
Tests E2E
Chaque requête validée
100%
Couverture de parité
Correspondance byte-à-byte
2
Moteurs de base
PostgreSQL & SQLite
3
Benchmarks ORM
Prisma v6/v7, Drizzle

Comment nous validons la correction

Chaque test suit un processus rigoureux en 5 étapes pour garantir que le SQL généré produit des résultats identiques à Prisma

1

Générer du SQL à partir d’une requête Prisma

Parser les arguments Prisma et générer un SQL équivalent avec les mêmes modèles et schéma. Le SQL généré utilise des requêtes paramétrées pour la sécurité et la performance.

2

Exécuter les deux requêtes en parallèle

Exécuter le SQL généré directement via postgres.js ou better-sqlite3, et exécuter la même requête via Prisma. Les deux ciblent le même état de base.

3

Normaliser les résultats

Gérer les différences de type (BigInt vs Number, précision Decimal, sérialisation Date) et normaliser l’ordre des clés d’objet pour une comparaison équitable.

4

Vérification d’égalité profonde

Vérifier une correspondance exacte : même nombre de lignes, mêmes valeurs de champs, mêmes relations imbriquées, même ordre. Tout écart fait échouer le test.

5

Mesurer la performance

Mesurer le temps d’exécution avec 5 warmups, puis moyenner 10–50 itérations par test. Comparer à Prisma v6, Prisma v7 et Drizzle ORM.

Techniques avancées de validation

Normalisation des types de données

  • Conversion BigInt: JavaScript BigInt → Number pour comparaison
  • Gestion des Decimal: Prisma Decimal → Float avec précision 10 chiffres
  • Normalisation des dates: Toutes les valeurs DateTime → null (focus données, pas timestamps)
  • Parsing JSON: Détection et parsing automatique de chaînes JSON
  • Tri des clés d’objet: Ordre alphabétique pour comparaison cohérente

Benchmarking des performances

  • Phase de warmup: 5 itérations pour amorcer caches et JIT
  • Itérations adaptatives: 5–50 runs selon la complexité
  • Mesure isolée: Chaque type de requête mesuré indépendamment
  • Comparaison multi-ORM: Prisma v6, v7, Drizzle, SQL généré
  • Temps de génération SQL: Mesure séparée de l’overhead de génération

Couverture de test complète

Les tests couvrent chaque opération de lecture Prisma à plusieurs niveaux de complexité

Opérations de requête

  • findMany avec filtres complexes
  • findFirst avec skip & pagination
  • findUnique par ID & champs uniques
  • count avec conditions WHERE
  • aggregate (sum, avg, min, max)
  • groupBy avec clauses HAVING

Scénarios complexes

  • Includes imbriqués (4 niveaux)
  • Filtres de relation (some/every/none)
  • Distinct avec window functions
  • Pagination par curseur
  • Select + include combinés
  • Comptages de relation (_count)

Types de filtres

  • Comparaison (lt/lte/gt/gte)
  • Logique (AND/OR/NOT)
  • Ops string (contains/startsWith)
  • Tests NULL (is/isNot)
  • IN/NOT IN tableaux
  • Modes de sensibilité à la casse

Tests PostgreSQL

  • ✓ Recherches insensibles à la casse via ILIKE
  • ✓ Opérations JSON/JSONB
  • ✓ Gestion des champs array
  • ✓ Support des types composites
  • ✓ Validation des window functions
  • ✓ Tests d’isolation de transaction

Tests SQLite

  • ✓ Pattern matching LIKE
  • ✓ Validation extension JSON1
  • ✓ Émulation window functions
  • ✓ Optimisation DISTINCT
  • ✓ Corrélation de sous-requêtes
  • ✓ Gestion de l’affinité texte

Exemple de cas de test

Voyez comment nous validons une requête imbriquée complexe avec des filtres de relation

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 internally:
// 1. Calls generateSQL() with the args
// 2. Executes generated SQL directly
// 3. Executes Prisma query
// 4. Normalizes both results
// 5. Deep equality check - fails if any difference
// 6. Benchmarks execution time

Ce qui se passe pendant l’exécution des tests

1. Génération de requête (microsecondes)

generateSQL() parse les args Prisma et crée du SQL paramétré. Cette étape est benchmarkée séparément pour mesurer l’overhead de génération.

2. Exécution en parallèle (millisecondes)

Les deux requêtes frappent simultanément le même état via Promise.all(), assurant une comparaison équitable et des conditions identiques.

3. Normalisation profonde

Normalisation récursive : BigInt→Number, Decimal→Float(10), Date→null, parsing JSON, tri des clés. Cela garantit une comparaison byte-à-byte.

4. Égalité stricte

Comparaison JSON stringify avec tolérance zéro. Tout écart de lignes, valeurs, objets imbriqués ou ordre fait échouer le test avec un diff détaillé.

5. Mesure de performance

Après validation, 5–50 itérations mesurent le temps moyen. Résultats : Prisma v6, Prisma v7, Drizzle ORM, SQL généré, et overhead de génération SQL.

Validation multi-versions

Chaque test s’exécute sur Prisma v6 et v7 pour assurer la compatibilité :

Prisma v6 (6.16.3)

  • • Usage direct de PrismaClient
  • • Architecture d’engine legacy
  • • Métriques de référence

Prisma v7 (7.2.0)

  • • Architecture basée sur adapters
  • • @prisma/adapter-pg & adapter-better-sqlite3
  • • Nouvelles optimisations d’engine

Rapports de benchmarks automatisés

Tous les résultats de benchmarks sont générés automatiquement et stockés en JSON pour une transparence totale :

benchmark-results/v6-postgres-latest.json
benchmark-results/v7-postgres-latest.json
benchmark-results/v6-sqlite-latest.json
benchmark-results/v7-sqlite-latest.json

Chaque fichier contient : nom de test, temps Prisma, temps SQL généré, temps Drizzle, ratios de speedup, et timestamp ISO.

Explorer la suite de tests complète

Les 137 tests sont open source. Consultez le code, les benchmarks et la logique de validation.