Créer une structure de base de données en mémoire à partir D'une instance Oracle
j'ai une application dans laquelle de nombreux "unité" les tests utilisent une connexion réelle à une base de données Oracle lors de leur exécution.
comme vous pouvez l'imaginer, ces tests prennent trop de temps à être exécutés, car ils ont besoin d'initialiser certains contextes de printemps, et de communiquer à L'instance Oracle. En plus de cela, nous devons gérer des mécanismes complexes, tels que des transactions, afin d'éviter des modifications de la base de données après l'exécution du test (même si nous utilisons des classes usefull à partir du Printemps comme ).
donc mon idée est de remplacer progressivement cette instance de test Oracle par une base de données en mémoire. Je vais utiliser hsqldb
ou peut-être mieux h2
.
Ma question est de savoir quelle est la meilleure approche pour le faire. Ma principale préoccupation est liée à la construction de la structure de la base de données en mémoire et à l'insertion de données de référence.
bien sûr, je peux extraire la structure de la base de données D'Oracle, utiliser certains outils comme SQL Developer
ou TOAD
, et ensuite modifier ces scripts pour les adapter à la hsqldb
ou h2
langue. Mais je ne pense pas que ce soit la meilleure approche.
en fait, j'ai déjà fait cela sur un autre projet en utilisant hsqldb
, mais j'ai écrit manuellement tous les scripts pour créer des tables. Heureusement, je n'avais que quelques tables pour créer. Mon principal problème durant cette étape était de "traduire" les scripts Oracle utilisés pour créer des tables dans le hsqldb
langue.
Par exemple, un tableau créé dans Oracle à l'aide de la commande sql suivante:
CREATE TABLE FOOBAR (
SOME_ID NUMBER,
SOME_DATE DATE, -- Add primary key constraint
SOME_STATUS NUMBER,
SOME_FLAG NUMBER(1) DEFAULT 0 NOT NULL);
besoin d'être "traduit" pour hsqldb
à:
CREATE TABLE FOOBAR (
SOME_ID NUMERIC,
SOME_DATE TIMESTAMP PRIMARY KEY,
SOME_STATUS NUMERIC,
SOME_FLAG INTEGER DEFAULT 0 NOT NULL);
dans mon projet actuel, il y a trop de tables pour le faire manuellement...
Alors mes questions:
- Quels sont les conseils que vous pouvez me donner pour réaliser cela?
h2
ouhsqldb
fournir certains outils pour générer leurs scripts à partir D'une connexion Oracle?
information technique
La Version 1.6 De Java, Spring 2.5, Oracle 10.g, Maven 2
Modifier
Quelques informations concernant mes tests d'unité:
Dans l'application où j'ai utilisé hsqldb
, j'ai eu les tests suivants:
- Quelques tests unitaires "de base", qui n'ont rien à voir avec la base de données.
- Pour le test DAO, j'ai utilisé hsqldb
pour exécuter des manipulations de bases de données, telles que CRUD.
- Ensuite, sur la couche service, j'ai utilisé Mockito
pour se moquer de mes objets DAO, afin de se concentrer sur le service de test et non pas à l'ensemble des applications (à savoir le service + dao + DB).
dans mon application actuelle, nous avons le pire scénario: les tests de la couche DAO ont besoin d'une connexion Oracle pour être exécutés. La couche services fait utilisez (encore) n'importe quel objet simulé pour simuler le DAO. De sorte que les services de tests besoin d'un Connexion Oracle.
je suis conscient que les moqueries et la base de données en mémoire sont deux points de séparation, et je vais les aborder dès que possible. Toutefois, la première étape est de pour supprimer la connexion Oracle par une base de données en mémoire, et puis j'utiliserai mon Mockito
connaissances pour améliorer les tests.
notez que je veux aussi séparer les tests unitaires des tests d'intégration. Ce dernier aura besoin d'un accès à la base de données Oracle, pour exécuter des tests "réels" , mais ma principale préoccupation (et c'est le but de cette question) Est que presque tous mes tests unitaires ne sont pas effectués isolément aujourd'hui.
4 réponses
utilisez une base de données en mémoire / Java pour les tests. Cela permettra de s'assurer que les tests sont plus près du monde réel que si vous essayez de "abstraire" la base de données dans votre test. Probablement de tels tests sont aussi plus faciles à écrire et à maintenir. D'un autre côté, ce que vous voulez probablement "abstraire" dans vos tests est L'UI, parce que les tests D'UI sont généralement difficiles à automatiser.
la syntaxe Oracle que vous avez posté fonctionne bien avec la base de données H2( je viens de le tester), donc il semble que H2 supporte le La syntaxe Oracle est meilleure que HSQLDB. Avertissement: je suis l'un des auteurs de H2. Si quelque chose ne fonctionne pas, veuillez l'afficher sur la liste de diffusion H2.
vous devriez de toute façon avoir les instructions DDL pour la base de données dans votre système de contrôle de version. Vous pouvez utiliser ces scripts pour les tests. Peut - être que vous devez également prendre en charge plusieurs versions de schema-dans ce cas, vous pouvez écrire des scripts de mise à jour de version (alter table...). Avec une base de données Java, vous pouvez également les tester.
par la façon, vous n'avez pas nécessairement besoin d'utiliser le mode en mémoire lorsque vous utilisez H2 ou HSQLDB. Les deux bases de données sont rapides même si vous persistez les données. Et ils sont faciles à installer (juste un fichier jar) et nécessitent beaucoup moins de mémoire Qu'Oracle.
dernière HSQLDB 2.0.1 prend en charge la syntaxe ORACLE pour DUAL, ROWNUM, NEXTVAL et CURRVAL via un drapeau de compatibilité syntaxique, sql.syntax_ora=true. De la même manière, la concaténation d'une chaîne avec une chaîne NULL et les restrictions sur NULL dans les contraintes uniques sont gérées avec d'autres drapeaux. La plupart des fonctions ORACLE comme TO_CHAR, TO_DATE, NVL etc. sont déjà intégrées.
pour le moment, pour utiliser des types ORACLE simples tels que NUMBER, vous pouvez utiliser une définition de type:
créer TAPEZ LE NUMÉRO NUMÉRIQUE
le prochain snapshot permettra le nombre (N) et d'autres aspects de la compatibilité de type ORACLE lorsque le drapeau est placé.
Télécharger à partir de http://hsqldb.org/support/
[Update:] le snapshot publié le 4 octobre traduit la plupart des types spécifiques D'Oracle en types SQL ANSI. HSQLDB 2.0 supporte également le type D'intervalle ANSI SQL et l'arithmétique date / timestamp de la même manière Qu'Oracle.
à quoi servent les tests de votre unité? S'ils testent le bon fonctionnement de DDLs et les procédures stockées, alors vous devriez écrire les tests "plus près" D'Oracle: soit sans code Java ou sans ressort et d'autres interfaces web nice se concentrant sur la base de données.
si vous voulez tester la logique de L'application implémentée en Java et Spring, vous pouvez utiliser des objets simulés/connexion à la base de données pour rendre vos tests indépendants de la base de données.
Si vous voulez tester le travail comme un ensemble (ce qui est contre le système modulaire de développement et de test principe), alors vous pouvez virtualiser votre base de données et de test sur cette instance, sans avoir le risque de faire une méchante des modifications irréversibles.
tant que vos tests se nettoient après eux-mêmes (comme vous semblez déjà savoir comment configurer), il n'y a rien de mal à lancer des tests contre une instance de base de données réelle. En fait, c'est l'approche que je préfère habituellement, parce que vous allez tester quelque chose aussi près de la production que possible.
les incompatibilités semblent petites, mais elles finissent vraiment par nous ronger le dos peu de temps après. Dans un bon cas, vous pouvez vous en tirer avec une traduction SQL désagréable / moquerie étendue. Dans le pire des cas, pièces du système sera juste impossible à tester, je pense que c'est un risque inacceptable pour les systèmes critiques.