Tests Méthodologie
137 tests end-to-end valident que chaque requête SQL générée correspond exactement à la sortie de Prisma
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
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.
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.
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.
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.
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
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.