Assurance qualité

Méthodologie de test

La validation actuelle couvre les lectures prises en charge sur PostgreSQL et SQLite, avec des rapports de benchmark pour Prisma v6, v7, v8, Drizzle et le SQL généré.

Suite E2E
Actuelle
Parité des requêtes validée
Couverture de parité
100%
Correspondance byte-à-byte
Moteurs de base
2
PostgreSQL & SQLite
Benchmarks ORM
4
Prisma v6/v7/v8, 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, Prisma v8 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 de 10 chiffres
Normalisation des dates
Toutes les valeurs DateTime → null (focus sur les données, pas les timestamps)
Parsing JSON
Détection et parsing automatiques des chaînes JSON
Tri des clés d’objet
Ordre alphabétique pour une 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é de la requête
Mesure isolée
Chaque type de requête mesuré indépendamment
Comparaison multi-ORM
Prisma v6, v7, v8, Drizzle, SQL généré
Temps de génération SQL
Mesure séparée de l’overhead de génération des requêtes

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)
  • Opérations sur chaînes (contains/startsWith)
  • Tests NULL (is/isNot)
  • Tableaux IN/NOT IN
  • 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 de l’extension JSON1
  • Émulation des 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 en interne :
// 1. Appelle generateSQL() avec les args
// 2. Exécute directement le SQL généré
// 3. Exécute la requête Prisma
// 4. Normalise les deux résultats
// 5. Vérification d’égalité profonde - échoue à la moindre différence
// 6. Mesure le temps d’exécution

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

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

    La fonction 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 des requêtes.

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

    Les deux requêtes ciblent simultanément le même état de base via Promise.all(), ce qui assure une comparaison équitable et des conditions de données identiques.

  3. 3Normalisation profonde

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

  4. 4Égalité stricte

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

  5. 5Mesure de performance

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

Validation multi-versions

Chaque test benchmarké s’exécute sur Prisma v6, v7 et v8 lorsque c’est pris en charge :

Prisma v6 (6.19.3)

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

Prisma v7 (7.10.0)

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

Prisma v8 (8.1.0-dev.1)

  • Couverture de la version dev de Prisma v8
  • Architecture basée sur des adapters
  • Parité des benchmarks PostgreSQL et SQLite

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 :

Explorer la suite de tests complète

La suite de validation et les rapports de benchmark sont open source. Consultez le code de test, les données de benchmark et les vérifications de parité.