PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Le mode postgresql H2 ne semble pas fonctionner pour moi

J'ai donc pensé à utiliser le mode de compatibilité H2 PosgreSQL en pensant que toutes les requêtes postgres fonctionneront sur H2, veuillez me corriger si je me trompe

J'ai bien peur que ce ne soit pas vrai.

H2 essaie d'émuler la syntaxe PostgreSQL et de prendre en charge quelques fonctionnalités et extensions. Il ne correspondra jamais entièrement au comportement de PostgreSQL et ne prend pas en charge toutes les fonctionnalités.

Les seules options que vous avez sont :

  • Utiliser PostgreSQL dans les tests ; ou
  • Cesser d'utiliser les fonctionnalités non prises en charge par H2

Je suggère d'utiliser Pg pour les tests. Il est relativement simple d'écrire un harnais de test qui initdb est une instance de postgres et de le lancer pour le tester puis de le démonter après.

Mise à jour basée sur les commentaires :

Il n'y a pas de ligne dure entre les tests " unitaires " et " d'intégration ". Dans ce cas, H2 est également un composant externe. Les tests unitaires puristes auraient un répondeur factice aux requêtes dans le cadre du harnais de test. Tester avec H2 est tout autant un test "d'intégration" qu'un test avec PostgreSQL. Le fait qu'il soit en cours de traitement et en mémoire est une commodité, mais n'est pas significatif sur le plan fonctionnel.

Si vous voulez tester unitaire vous devez écrire une autre cible de base de données pour que votre application accompagne vos cibles "PostgreSQL", "SybaseIQ", etc. Appelez-le, disons, "MockDatabase". Cela devrait simplement renvoyer les résultats attendus des requêtes. Il n'exécute pas vraiment les requêtes, il n'existe que pour tester le comportement du reste du code.

Personnellement, je pense que c'est une énorme perte de temps, mais c'est ce qu'un puriste des tests unitaires ferait pour éviter d'introduire des dépendances externes dans le harnais de test.

Si vous insistez pour avoir des tests unitaires (par opposition à l'intégration) pour vos composants de base de données mais que vous ne pouvez pas/ne voulez pas écrire une interface fictive, vous devez plutôt trouver un moyen d'en utiliser une existante. H2 serait un candidat raisonnable pour cela - mais vous devrez écrire un nouveau backend avec un nouvel ensemble de requêtes qui fonctionnent pour H2, vous ne pouvez pas simplement réutiliser votre backend PostgreSQL. Comme nous l'avons déjà établi, H2 ne prend pas en charge toutes les fonctionnalités dont vous avez besoin avec PostgreSQL, vous devrez donc trouver différentes façons de faire les mêmes choses avec H2. Une option serait de créer une simple base de données H2 avec des résultats "attendus" et des requêtes simples qui renvoient ces résultats, en ignorant complètement le schéma de l'application réelle. Le seul véritable inconvénient ici est que cela peut être très pénible à maintenir... mais c'est du test unitaire.

Personnellement, je testerais juste avec PostgreSQL. À moins que je ne teste des classes ou des modules individuels qui sont autonomes en tant qu'unités bien définies à interface étroite, peu m'importe que quelqu'un appelle cela un test "d'unité" ou "d'intégration". Je vais tester unitairement, disons, les classes de validation de données. Pour les puristes de code d'interface de base de données, les tests unitaires n'ont que peu de sens et je me contenterai de faire des tests d'intégration.

Bien qu'une base de données en mémoire en cours de traitement soit pratique pour cela, elle n'est pas obligatoire. Vous pouvez écrire votre harnais de test afin que le code de configuration initdb s un nouveau PostgreSQL et le lance ; puis le code de démontage tue le postmaster et supprime le datadir. J'ai écrit plus à ce sujet dans cette réponse.

Voir aussi :

  • Exécuter PostgreSQL uniquement en mémoire

Quant à :

Si toutes les requêtes avec les ensembles de données de fin attendus fonctionnent correctement dans Postgress, je peux supposer que cela fonctionnera correctement dans toutes les autres bases de données

Si je comprends bien ce que vous dites, alors oui, c'est le cas - si le reste de votre code fonctionne avec un jeu de données de PostgreSQL, il devrait généralement fonctionner de la même manière avec un jeu de données contenant les mêmes données d'une autre base de données. Tant qu'il utilise des types de données simples et non des fonctionnalités spécifiques à la base de données, bien sûr.