Comment faire pour simuler un DB pour les tests (Java)?
Je suis à la programmation en Java et mes applications sont faites beaucoup de l'utilisation de la DB. Par conséquent, il est important pour moi d'être en mesure de tester ma DB utilisation facilement.
Ce DB tests sont tout au sujet? Pour moi, ils devraient l'approvisionnement de deux exigences simples:
- Vérifier la syntaxe SQL.
- Plus important encore, de vérifier que les données sont sélectionnées, mis à jour correctement inséré, selon une situation donnée.
Eh bien, il semble que tout ce que je besoin est un DB.
Mais en fait, je ne préfère pas, comme il y a peu de difficultés à l'aide d'un DB pour un test:
- "Juste obtenir vous-même un test DB, comment dur peut-il être?" - Eh bien, dans mon lieu de travail, avoir un personnel de test DB est assez impossible. Vous devez utiliser un "public" de la DB, qui est accessible pour tout le monde.
- "Ces tests sûr, c'est pas du rapide..." - DB tests ont tendance à être plus lent que d'habitude tests. C'est vraiment pas l'idéal pour se ralentir tests.
- "Ce programme doit traiter tous les cas!" - Il devient un peu ennuyeux et même impossible de les essayer et de simuler tous les cas dans une DB. Pour chaque cas, une certaine quantité de requêtes insert/update devrait être fait, ce qui est ennuyeux et prend du temps.
- "Attendez une seconde, comment savez-vous il y a 542 lignes dans cette table?" - L'un des grands principes de l'essai, est d'être en mesure de tester la fonctionnalité d'une manière différente de celle de votre test de code. Lors de l'utilisation de la base de données, il est généralement un moyen de faire quelque chose, donc le test est exactement la même que la base de code.
Donc, vous pouvez comprendre que je n'aime pas DBs quand il s'agit de tests (bien sûr, je vais avoir à obtenir dans un certain point, mais je préfère y aller plus tard sur mes tests, après j'ai trouvé la plupart des bugs en utilisant le reste de l'méthodes d'essai). Mais ce que je cherche?
Je suis à la recherche d'un moyen de simuler une DB, un simulacre DB, en utilisant le système de fichiers ou tout simplement de la mémoire virtuelle. J'ai pensé que peut-être il y a un outil Java/package qui permet simplement de construire (en utilisant le code de l'interface) d'une base de maquette par test, avec des tables et des lignes, avec SQL vérification, et avec un code d'interface pour le suivi de son état (plutôt qu'à l'aide de SQL).
Êtes-vous familier avec ce genre d'outil?
Edit: Merci pour les réponses! Même si j'ai été demander à un outil de, vous aussi m'a fourni des conseils concernant le problème 🙂 Ça va me prendre un certain temps pour vérifier vos offres, donc je ne peux pas dire pour l'instant si vos réponses satisfaisaient pas.
De toute façon, voici une meilleure vue de ce que je suis à la recherche pour - Imagine une classe nommée DBMonitor, que l'une de ses caractéristiques est de trouver le nombre de lignes dans une table. Voici un imaginaire code de la façon dont je voudrais tester cette fonctionnalité en utilisant JUnit:
public class TestDBMonitor extends TestCase {
@Override
public void setUp() throws Exception {
MockConnection connection = new MockConnection();
this.tableName = "table1";
MockTable table = new MockTable(tableName);
String columnName = "column1";
ColumnType columnType = ColumnType.NUMBER;
int columnSize = 50;
MockColumn column = new MockColumn(columnName, columnType, columnSize);
table.addColumn(column);
for (int i = 0; i < 20; i++) {
HashMap<MockColumn, Object> fields = new HashMap<MockColumn, Object>();
fields.put(column, i);
table.addRow(fields);
}
this.connection = connection;
}
@Test
public void testGatherStatistics() throws Exception {
DBMonitor monitor = new DBMonitor(connection);
monitor.gatherStatistics();
assertEquals(((MockConnection) connection).getNumberOfRows(tableName),
monitor.getNumberOfRows(tableName));
}
String tableName;
Connection connection;
}
J'espère que ce code est assez clair pour comprendre mon idée (excusez-moi pour les erreurs de syntaxe, j'ai été taper manuellement sans mes chers Eclipse :P).
En passant, j'utilise un ORM partiellement, et mes premières requêtes SQL sont assez simple et ne devrait pas varier d'une plateforme à une autre.
Vous devez vous connecter pour publier un commentaire.
nouvelle réponse à la vieille question (mais les choses ont avancé un peu):
vous n'avez pas le simuler. vous vous moquez de votre repositiories et vous n'avez pas de test ou d'utiliser le même db dans vos tests et vous tester votre sql. Tous en mémoire dbs ne sont pas entièrement compatibles, de sorte qu'ils ne seront pas vous donner une couverture complète et la fiabilité. et jamais, jamais, jamais essayer de se moquer de/de simuler la profondeur db objets comme connexion, ensemble de résultats etc. il vous donne pas de valeur à tous et c'est un cauchemar pour développer et maintenir
malheureusement, beaucoup d'entreprises utilisent encore ce modèle, mais maintenant nous avons docker et il y a des images pour presque tous les db. les produits commerciaux sont soumis à certaines limites (jusqu'à quelques go de données) qui sont non-important pour les tests. aussi vous avez besoin de votre schéma et de la structure à créer sur cette bd locale
oui, db tests sont plus lentes, mais elles ne sont pas si lent. J'ai fait quelques simples les mesures et un type de test s'5-50ms. ce qui prend du temps est le démarrage de l'application. il ya beaucoup de façons pour accélérer le processus:
vous pouvez également mettre tout le db en tmpfs
une autre stratégie est utile d'avoir des groupes de tests et de garder db tests désactivé par défaut (si vraiment ils ne ralentit votre build). de cette façon, si quelqu'un est vraiment en train de travailler sur db, il suffit de passer le drapeau supplémentaire dans la ligne de cmd ou de l'utilisation de l'IDE (testng groupes et custom test (test personnalisé sélecteurs sont parfait pour cela)
"prend le temps" de la partie a été discuté ci-dessus. est-il gênant? J'ai vu deux façons:
count(*)
dans l'essai B ne fonctionne pas. il ne pousse parce que même si vous supprimez quelques tests, vous ne savez pas quelles lignes ont été utilisés uniquement par ce testeuh... pas vraiment. le principe est de vérifier si votre logiciel génère de sortie souhaité en réponse à une entrée spécifique. donc, si vous appelez
dao.insert
542 fois et puis votredao.count
retourne 542, cela signifie que votre logiciel fonctionne comme spécifié. si vous le souhaitez, vous pouvez appeler commit/drop cache entre les deux. Bien sûr, parfois vous voulez tester votre mise en place du contrat et puis vous vérifiez si votre dao changé l'état de la db. mais vous avez toujours tester sql Une aide de sql B (insérer vs sélectionner, séquence next_val vs valeur retournée etc). oui, vous aurez toujours le problème de "qui permettra de tester mes tests", et la réponse est: on ne, alors gardez-les simples!d'autres outils qui peuvent vous aider:
testcontainers va vous aider à fournir
réel db.
dbunit - vous aidera à nettoyer les données entre les tests
contre:
testegration - intentions pour vous fournir complet, prêt à l'emploi et extensible cycle de vie (divulgation: je suis un créateur).
contre:
la voie de migration ou liquibase - db outils de migration. ils vous aider à créer facilement un schéma et toutes les structures de votre région db pour les tests.
Java est livré avec Java DB.
Cela dit, je vous déconseillons d'utiliser un autre type de DB que ce que vous utilisez dans la production, sauf si vous passez par un ORM couche. Sinon, votre SQL n'est peut être pas de la croix-plate-forme que vous le pensez.
Également vérifier DbUnit
J'ai utilisé Hypersoniques à cette fin. En gros, c'est un fichier JAR (un pur Java base de données en mémoire) que vous pouvez exécuter dans sa propre JVM ou dans votre propre JVM et en cours d'exécution, vous avez une base de données. Puis vous arrêter et de votre base de données s'en va. Je l'ai utilisé jusqu'à présent -- uniquement comme une base de données en mémoire. Il est très simple de démarrer et d'arrêter via Ant lors de l'exécution des tests unitaires.
Il y a beaucoup de points de vue sur la façon de tester l'intégration des points tels que la connexion de Base de données via SQL. Mon ensemble de règles qui a bien fonctionné pour moi, est comme suit:
1) Séparer la Base de données d'accéder à la logique et les fonctions générales de la logique métier et de le cacher derrière une interface.
Raison: afin de tester la grande majorité de la logique du système, il est préférable d'utiliser un mannequin/stub en place de la base de données comme sa plus simple expression.
Raison 2: Il est beaucoup plus rapide
2) Traiter les tests dans la base de données des tests d'intégration qui sont séparés du corps principal de tests unitaires et besoin pour exécuter un programme d'installation de la base de données
Raison: la Vitesse et de la qualité des tests de
3) Tous les développeurs ont besoin de leur propre base de données. Ils auront besoin d'un système automatisé de mise à jour de sa structure basée sur les modifications de leurs coéquipiers et de présenter des données. Voir les points 4 et 5.
4) Utiliser un outil comme http://www.liquibase.org pour gérer les mises à niveau dans vos bases de données de la structure.
Raison: vous Donne de l'agilité dans la capacité de modifier la structure actuelle et aller de l'avant dans les versions
5) Utiliser un outil comme http://dbunit.sourceforge.net/ pour gérer les données. Configurer les fichiers de scénario (xml ou XLS) pour notamment des cas de test et des données de base et claires de ce qui est nécessaire à un cas de test.
La raison: Beaucoup mieux qu'à la main de l'insertion et de suppression de données
Raison 2: plus Facile pour les testeurs de comprendre comment ajuster les scénarios
Raison 3: Son plus rapide pour exécuter cette
6) Vous avez besoin de tests fonctionnels, qui ont aussi des DBUnit tout comme le scénario de données, mais ce sont de loin les plus grands ensembles de données, et l'exécution de l'ensemble du système. Ceci termine l'étape de combiner les connaissances que
a) L'unité exécution des tests et donc la logique est bonne
b) Que les tests d'intégration à la base de données, exécuter et SQL est correcte
résultant dans "et l'ensemble du système fonctionne comme un haut vers le bas de la pile"
Cette combinaison m'a bien servi jusqu'à présent pour atteindre une haute qualité des tests et des produits ainsi que le maintien de la vitesse de test de l'unité de développement et de l'agilité au changement.
Les sons que vous avez des problèmes culturels au travail, en fournissant une barrière à vous d'être en mesure de faire votre travail au maximum de vos capacités et de l'intérêt de votre produit. Vous voulez peut-être faire quelque chose à ce sujet.
D'autre part, si votre schéma de base de données est sous contrôle de version, alors vous pourriez toujours avoir un test de construire qui crée une base de données à partir du schéma, le remplit avec les données de test, exécute vos tests, rassemble les résultats, puis les gouttes de la base de données. Il avait seulement être dans l'existence pour la durée des tests. Il peut être une nouvelle base de données sur une installation existante si le matériel est un problème. Ceci est similaire à ce que nous faisons, où je travaille.
Si vous utilisez Oracle au travail, vous pouvez utiliser le Point de Restauration dans les Flashback fonctionnalité de Base de données pour la base de données de retour d'un temps avant de vos tests. Cela va effacer toutes les modifications que vous faites personnellement à la DB.
Voir:
https://docs.oracle.com/cd/E11882_01/backup.112/e10642/flashdb.htm#BRADV71000
Si vous avez besoin d'une base de données de test pour une utilisation avec l'Oracle de production/travail de recherche de la XE, express edition base de données d'Oracle. Ce service est gratuit pour un usage personnel, avec une limite de base de données de moins de 2 go en taille.
Nous avons récemment passé à JavaDB ou Derby à mettre en œuvre. Derby 10.5.1.1 implémente désormais d'une représentation en mémoire de sorte qu'il court très vite, il n'a pas besoin d'aller sur le disque:
Derby Dans La Mémoire De L'Apprêt
Nous la conception de notre application à exécuter sur Oracle, PostgreSQL et Derby, afin de ne pas aller trop loin en bas de la route sur une plate-forme, avant de découvrir qu'une base de données prend en charge une fonctionnalité que d'autres ne le font pas.
Je suis d'accord avec banjollity. La configuration de développement isolé des environnements de test et devrait être une priorité élevée. Chaque système de base de données que j'ai utilisé est soit open source ou libre developer edition, vous pouvez installer sur votre poste de travail local. Cela vous permet de vous développer à l'encontre de la même base de données dialecte de la production, vous donne le plein accès admin pour le développement de bases de données et est plus rapide que d'utiliser un serveur distant.
Essayez d'utiliser derby. Il est facile et portable. Avec mise en veille prolongée de votre application devient flexible. Essai sur derby, la production sur tout ce que vous aimez et de confiance.
Nous sommes en train de créer une base de données de test de l'environnement au travail dès maintenant. Nous sentons que nous devons utiliser un réel système de gestion de base avec données simulées. Un problème avec une simulation de SGBD SQL jamais vraiment totalement gélifié comme un standard, donc artificielle, essais d'environnement aurait à soutenir fidèlement notre base de données de production du dialecte. Un autre problème est que nous faisons un usage intensif de la valeur de la colonne contraintes, les contraintes de clés étrangères, et les contraintes unique, et depuis artificielle outil ne serait probablement pas mettre en œuvre ces, nos tests unitaires pourrait passer, mais notre système de tests échouent quand ils ont d'abord frappé les contraintes réelles. Si les tests sont trop longues, cela indique une erreur d'implémentation et de nous régler nos requêtes (généralement des ensembles de données de test sont minuscules par rapport à la production).
Nous avons installé un vrai SGBD sur chaque ordinateur du développeur et sur notre intégration continue et le serveur de test (nous utilisons Hudson). Je ne sais pas ce que votre travail de la politique de restriction, mais il est assez facile à installer et à utiliser PostgreSQL, MySQL et Oracle XE. Ces sont tous gratuits pour le développement de l'utilisation (même Oracle XE), donc il n'y a aucune raison rationnelle à interdire leur utilisation.
La question clé est de savoir comment pouvez-vous garantir que les tests de toujours commencer avec la base de données dans un état cohérent? Si les tests étaient tous en lecture seule, pas de problème. Si vous pouviez ingénieur mutation des tests de toujours lancer dans des opérations qui ne sont jamais commettre, pas de problème. Mais en général, vous avez besoin de s'inquiéter à propos de l'inversion des mises à jour. Pour ce faire, vous pouvez exporter l'état initial vers un fichier, puis de l'importer retour post-test (Oracle de l'exp et de la pmi, des commandes shell ce faire). Ou vous pouvez utiliser un point de contrôle/restauration. Mais d'une façon plus élégante est d'utiliser un outil comme dbunit, qui fonctionne bien pour nous.
Le principal avantage de cela est que nous sommes en mesure de capturer plus de bugs à l'avant où ils sont beaucoup plus faciles à corriger et notre véritable test de système n'est pas bloqué pendant que les développeurs fébrilement essayez de déboguer des problèmes. Cela signifie nous produisons un code de meilleure qualité plus rapidement et avec moins d'effort.
Vous pourriez HSQLDB pour les en mémoire db test. Le démarrage de la mémoire de la base de données et l'exécution des tests, il est assez simple.
http://hsqldb.org/
Je pense que mon Acolyte cadre peut être utilisé pour de telles DB maquette: https://github.com/cchantep/acolyte .
Il permet de lancer Java (pour les tests) avec les connexions de vous l'homme de requête/mise à jour de la manipulation: de retour appropriée des jeux de résultats, nombre de mise à jour ou d'avertissement en fonction de l'exécution des cas.
Bien pour commencer ,êtes-vous en utilisant toutes les ORM Couche de DB d'accès?
Si non : alors ce que vous pensez serait d'aucune utilité.Quelle est l'utilisation de tests lorsque vous n'êtes pas sûr que SQL vous êtes de cuisson sera de travailler avec votre base de données en production qu'en cas de test que vous utilisez autre chose.
Si oui:vous pouvez Ensuite examiner les diverses options souligné.
jOOQ est un outil qui, en plus d'offrir d'abstraction SQL a aussi des petits outils intégrés comme un SPI qui permet de se moquer de la totalité de JDBC. Cela peut fonctionner de deux manières comme indiqué dans ce post de blog:
Par la mise en œuvre de la
MockDataProvider
SPI:Dans le ci-dessus la mise en œuvre, par programme d'interception de toutes les instructions SQL et retourne le résultat, et ce, même de façon dynamique par "analyse" de la chaîne SQL pour extraire des prédicats /informations sur la table, etc.
À l'aide de la plus simple (mais moins puissant)
MockFileDatabase
... qui a un format tel que la suite (un jeu de déclaration /résultat paires):
Le fichier ci-dessus peuvent alors être lus et utilisés comme suit:
Avis de la façon dont on utilise l'API JDBC directement, sans connexion à une base de données.
Ne remarque, je travaille pour le vendeur de jOOQ si cette réponse est biaisée.
Méfiez-vous, à un certain point, vous êtes à la mise en œuvre d'un ensemble de base de données
Les travaux ci-dessus pour les cas simples. Mais méfiez-vous que, finalement, vous allez mettre en œuvre une base de données entière. Vous souhaitez:
OK, en se moquant de la base de données comme indiqué ci-dessus, vous pouvez vérifier la syntaxe, parce que chaque syntaxe que vous n'avez pas prévu dans le exacte version comme indiqué ci-dessus sera rejetée par ces moqueries approche.
Vous pourriez mettre en œuvre un analyseur qui analyse le SQL (ou, encore, l'utilisation de jOOQ), puis de transformer l'instruction SQL dans quelque chose que vous pouvez plus facilement reconnaître et de produire un résultat. Mais en fin de compte, cela signifie simplement que la mise en œuvre d'une base de données entière.
Ce qui rend les choses encore plus difficile. Si vous exécutez une insertion et ensuite mettre à jour, le résultat est évidemment différente de d'abord mettre à jour, puis insérer, comme la mise à jour peut ou peut ne pas affecter la ligne insérée.
Comment vous assurez-vous que ce qui se passe quand "moqueur" une base de données? Vous avez besoin d'une machine d'état qui se souvient de l'état de chaque "moqué" de la table. En d'autres termes, vous allez mettre en œuvre une base de données.
Moqueur ne vous prendra pas plus loin
Comme piotrek mentionné, trop, en se moquant ne vous prendra pas plus loin. Il est utile dans les cas simples lorsque vous avez besoin d'intercepter seulement quelques très connu des requêtes. Il est impossible, si vous voulez vous moquer de la base de données pour l'ensemble d'un système. Dans ce cas, l'utilisation d'une base de données réelle, idéalement le même produit que vous utilisez dans la production.