web-dev-qa-db-fra.com

Existe-t-il un framework de type dbunit qui ne craint pas Java/scala?

Je pensais créer un nouveau cadre de travail léger pour la base de données. Je déteste absolument dbunit. Avant de le faire, je veux savoir si quelqu'un l'a déjà fait.

Ce que je n'aime pas chez dbunit:

1) Le format le plus simple à écrire et à utiliser est obsolète. Ils veulent que vous utilisiez des formats surchargés. Certains ont même besoin de schémas XML. Oui peut importe.

2) Ils remplissent les lignes non dans l'ordre dans lequel vous les écrivez, mais dans l'ordre, les tables sont définies dans le fichier xml. C'est vraiment dommage car vous ne pouvez pas commander vos données de manière à ce que les contraintes de clé étrangère ne posent aucun problème. Cela vous oblige simplement à vous efforcer de les désactiver complètement. 

Cela fait également perdre du temps et alourdit vos classes de base Junit pour inclure du code permettant de désactiver les contraintes de clé étrangère. Vous devrez probablement tester le type de base de données (hsqldb, etc.) et les désactiver de manière spécifique. C'est vraiment nul.

Cela pourrait être mieux si dbunit aidait à désactiver automatiquement les contraintes de clé étrangère dans le cadre de leur cadre, mais cela ne se produit pas. Ils gardent une trace des dialectes ... alors pourquoi ne pas les utiliser pour cela? En fin de compte, tout cela oblige le programmeur à perdre du temps et à ne pas se lever et faire des tests rapidement.

3) XML est une tâche difficile à écrire. Je n'ai pas besoin d'en dire plus à ce sujet. Ils offrent aussi tellement de façons de le faire que je pense que cela ne fait que compliquer les choses. Juste offrir un moyen vraiment solide et être fait avec elle.

4) Lorsque vos données deviennent volumineuses, garder une trace des identifiants et de leurs relations cohérentes/correctes est une douleur royale. 

En outre, si vous ne travaillez pas sur un projet pendant un mois, comment vous rappeler que user_id 1 était un administrateur, user_id 2 était un utilisateur professionnel, user_id 3 était un ingénieur et user_id 4 était autre chose? Revenir pour vérifier cela perd plus de temps. Il devrait y avoir un moyen significatif de le récupérer autrement qu’un nombre arbitraire.

5) c'est lent. J'ai constaté que, sauf si hsqldb est utilisé, il est terriblement lent. Ce n'est pas obligé. Il existe également de nombreuses façons de gâcher sa configuration, car il n’est pas facile de le faire «par défaut». Il y a une bosse que vous devez traverser pour le faire fonctionner correctement. Tout cela ne fait qu'encourager les gens à ne pas l'utiliser, ou à être énervé quand ils commencent à l'utiliser.

6) Certaines valeurs ont tendance à se répéter, aime les dates. Il serait bien de spécifier des valeurs par défaut, ou même de faire en sorte que le cadre en définisse automatiquement les valeurs par défaut, même sans que vous lui demandiez de définir les valeurs par défaut. De cette façon, vous pouvez créer des objets avec les valeurs souhaitées et laisser le reste de côté. Cela vaut certainement mieux que de spécifier chaque recoin d’une colonne si elle n’est pas requise.

7) La chose la plus ennuyante est probablement que la première entrée doit inclure TOUTES les valeurs - même les espaces réservés nuls - ou les futures lignes ne choisiront pas les colonnes que vous avez réellement spécifiées.

DBunit n'a pas non plus de valeur par défaut raisonnable pour la traduction de [NULL] en une valeur null réelle. Vous devez l'ajouter manuellement. Dis-moi, qui n'a pas fait ça avec dbunit? Tout le monde a. Ça ne devrait pas être comme ça!

Cela signifie que si vous avez un objet polymorphe, vous devez déclarer toutes les clés étrangères dans les tables de jointure de chaque sous-classe de la première ligne, même si elles sont nulles. Si vous créez une table pour tous les modèles de sous-classes, vous devez toujours spécifier tous les champs de la première ligne. C'est juste horrible.

Y a-t-il quelque chose qui me satisfasse ou devrais-je devenir le prochain développeur d'un meilleur framework de test de bases de données?

59
egervari

Je ne connais aucune alternative réelle à DbUnit et aucun des outils mentionnés par @Joe n'est à mes yeux:

  • Incanto : pas agnostique DB
  • SQLUnit : un harnais de régression et de tests unitaires permettant de tester les procédures stockées de la base de données (ce n'est pas le propos de DbUnit)
  • Cactus : un outil de test In-container (je ne vois pas en quoi cela aide les bases de données)
  • Liquibase : un outil de migration de base de données (ne charge/vérifie pas les données)
  • ORMUnit : peut initialiser une base de données mais c'est tout
  • JMock : ne concurrence pas du tout DbUnit

Cela dit, j’ai personnellement utilisé DbUnit avec succès à plusieurs reprises, sur des projets volumineux et de grande taille, et je le trouve plutôt utilisable, en particulier lors de l’utilisation de Unitils et de son module DbUnit. Cela ne signifie pas qu'il est parfait et ne peut pas être amélioré, mais avec un outillage correct (fabriqué sur mesure ou similaire à Unitils), son utilisation a été une expérience décente.

Alors laissez-moi répondre à certains de vos points:

1) Le format le plus simple à écrire et à utiliser est obsolète. Ils veulent que vous utilisiez des formats surchargés. Certains ont même besoin de schémas XML. Oui peut importe.

DbUnit prend en charge XML, XLS, CSV plat ou structuré. Quel format révolutionnaire voudriez-vous utiliser? À propos, une DTD ou un schéma n'est pas obligatoire lors de l'utilisation de XML. Mais cela vous donne de bonnes choses comme la validation et l'auto-complétion, comment est-ce mauvais? Et Unitils peut le générer facilement pour vous, voir Générer un XSD ou une DTD de la structure de base de données .

Cela pourrait être mieux si dbunit aidait à désactiver automatiquement les contraintes de clé étrangère dans le cadre de leur cadre, mais cela ne se produit pas. Ils gardent une trace des dialectes ... alors pourquoi ne pas les utiliser pour cela? En fin de compte, tout cela oblige le programmeur à perdre du temps et à ne pas se lever et faire des tests rapidement.

Ils attendent votre patch. 

Parallèlement, Unitils prend en charge la gestion transparente des contraintes, voir Désactivation des contraintes et mise à jour des séquences

3) XML est une tâche difficile à écrire. Je n'ai pas besoin d'en dire plus à ce sujet. Ils offrent aussi tellement de façons de le faire que je pense que cela ne fait que compliquer les choses. Juste offrir un moyen vraiment solide et être fait avec elle.

Je suppose que la douleur est subjective, mais je ne la trouve pas douloureuse, en particulier lors de l'utilisation d'un schéma et de l'auto-complétion. Quelle est la solution miracle que vous proposez?

4) Lorsque vos données deviennent volumineuses, garder une trace des identifiants et de leurs relations cohérentes/correctes est une douleur royale. 

Gardez-les petits, c'est un savoir meilleure pratique . Vous allez à l'encontre d'une pratique exemplaire connue et vous vous plaignez ensuite ... 

En outre, si vous ne travaillez pas sur un projet pendant un mois, comment vous rappeler que user_id 1 était un administrateur, user_id 2 était un utilisateur professionnel, user_id 3 était un ingénieur et user_id 4 était autre chose? Revenir pour vérifier cela perd plus de temps. Il devrait y avoir un moyen significatif de le récupérer autrement qu’un nombre arbitraire.

Oui, le changement de tâche est contre-productif. Mais comme vous travaillez avec des données de bas niveau, vous devez savoir comment elles sont représentées. Il n’existe de solution magique que si vous utilisez une API de niveau supérieur bien sûr (mais ce n’est pas l’objet de DbUnit).

5) c'est lent. J'ai constaté que, sauf si hsqldb est utilisé, il est terriblement lent. Ce n'est pas obligé. Il existe également de nombreuses façons de gâcher sa configuration, car il n’est pas facile de le faire «par défaut». Il y a une bosse que vous devez traverser pour le faire fonctionner correctement. Tout cela ne fait qu'encourager les gens à ne pas l'utiliser, ou à être énervé quand ils commencent à l'utiliser.

C'est inhérent aux bases de données et à JDBC, pas à DbUnit. Utilisez une base de données rapide comme H2 si vous voulez que les choses soient aussi rapides que possible (si vous avez une meilleure méthode agnostique pour faire les choses, je serais ravi de les apprendre).

6) La chose la plus ennuyante est probablement que la première entrée doit inclure TOUTES les valeurs - même les espaces réservés nuls - ou les futures lignes ne choisiront pas les colonnes que vous avez réellement spécifiées.

Pas avec Unitils comme mentionné dans les présentations telles que Unitils - Home - JavaPolis 2008 ou Tests unitaires: unitils & dbmaintain

Y a-t-il quelque chose qui me satisfasse ou devrais-je devenir le prochain développeur d'un meilleur framework de test de bases de données?

Si vous pensez pouvoir améliorer les choses, contribuez peut-être aux solutions existantes. Si ce n'est pas possible et si vous pensez pouvoir créer le framework de test de base de données Killer, que puis-je dire, faites-le. Mais n'oubliez pas que les discours sont faciles, proposer des solutions en utilisant vos propres solutions l'est moins.

96
Pascal Thivent

En tant que développeur DbUnit, je suis reconnaissant des critiques et je suis partiellement d'accord avec vous. Nous commençons actuellement la conception de la prochaine version majeure de DbUnit et je souhaite vous inviter à participer à la discussion et au développement.

Je ne vais pas répondre à vos questions car votre question ne concerne pas vraiment DbUnit, mais les alternatives DbUnit. Quoi qu'il en soit, je tiens simplement à souligner que votre point 7 est complètement faux: vous n'avez plus besoin de spécifier toutes les colonnes de la première ligne, cette fonctionnalité est appelée détection de colonne. Je ne vais pas vous dire pourquoi il n'est pas activé par défaut car vous êtes sûrement assez intelligent pour le comprendre vous-même.

Je vais faire un examen approfondi de la part de scaladbtest dans l’espoir que nous pourrons intégrer leurs idées.

26

Face à des préoccupations similaires en utilisant DBUnit, j'ai trouvé ceci: http://dbsetup.ninja-squad.com/index.html qui peut répondre à des préoccupations. Ainsi, au lieu de représenter les données de test dans des fichiers séparés, tout le contenu de la base de données est contenu dans la classe Java elle-même.

16
blue-sky

Si vous utilisez Spring Framework (ou ne l’utilisez pas du moins pour le tester), alors Spring DBUnit est actuellement la meilleure alternative (maintenue) à DBUnit que je connais et que j’utilise. Citant leur site web:

Spring DBUnit fournit une intégration entre les tests Spring cadre et le projet DBUnit populaire. Il vous permet de configurer et démonter les tables de la base de données en utilisant de simples annotations et en vérifiant contenu attendu de la table une fois le test terminé.

Spring DBUnit semble être la solution Spring «un peu officielle» pour le test des unités de base de données (avec DBUnit); au moins l'auteur/responsable de la bibliothèque, Phil Webb, travaille chez SpringSource/Pivotal.

4
Chriki

J'utilise DBUnit, avec quelques wrappers pour lisser les aspérités. Un outil intéressant qui peut compléter ou superposer la fonctionnalité est Jailer . Il peut extraire des sous-ensembles de données d'une base de données de référence et les stocker sous forme de fichiers XML compatibles DBUnit ou de "fichiers DML triés topologiquement", qui respectent les contraintes de clé étrangère.

3
retronym

Vous faites un excellent point. 

J'ai travaillé pour beaucoup de portails Web au cours des dernières années, principalement avec PHP, mais aussi un peu de Java de temps en temps.
Et comme vous, je ne comprends pas qu'après toutes ces années de développement et que les développeurs ne semblent pas se rendre compte à quel point la gestion du stockage a changé au cours de la dernière décennie . Il ne suffit pas d’envoyer simplement créer/insérer/tronquer des instructions à une base de données! Si vous travaillez à grande échelle, vous finissez par employer toutes sortes de systèmes de stockage, organisés en couches pour pousser rapidement le contenu à chaud. En plus de la base de données, il y a le problème du partitionnement des données. Si vous ne disposez pas d'une abstraction de clé étrangère appropriée, vous allez certainement perdre la tête lorsque la configuration de votre stockage change. Et pendant que nous y sommes: la commande de luminaires par priorité de clé étrangère présente de nombreux pièges et je n’ai pas encore vu de solution réelle pour cela avec DBUnit

Quoi qu’il en soit, le fait d’avoir juste un stockage de base de données de base en place pour l’analyse simple n’est pas suffisant pour les configurations de stockage complexes, car elles échouent souvent à reproduire les problèmes dans l’environnement réel et sont difficiles à maintenir. 

Sans vouloir ressembler à un fanboy: un endroit où tout va bien est le Ruby on Rails..__, qui a un concept de modèle persistant auquel les gens semblent avoir réellement réfléchi. Si vous utilisez PHP, Symfony est l'endroit où aller. Il est limité via l'inclusion par défaut de Doctrine, avec également une base de données plutôt centrée sur la base de données, mais il possède des interfaces propres, une grande extensibilité et une copie complète du système de fixation Rails. Professionnellement, je dois m'en tenir aux solutions homebrew pour l'instant, mais elles fonctionnent bien.

2
carrion

Je viens de publier une bibliothèque appelée JDBDT (Java Database Delta Testing) que vous pouvez utiliser pour configurer et valider une base de données lors de tests de logiciels.

Regardez http://jdbdt.org

Le mieux, Eduardo

2
edrdo

Voici une courte liste de quelques outils (en plus de DBunit) que je préfère ou trouve intéressants. À tout le moins, ils peuvent offrir une certaine inspiration:

Notez qu'aucun de ceux-ci n'est réellement concurrent de DBunit en termes de portée ou de jeu de fonctionnalités. Cependant, certaines idées intéressantes méritent d’être examinées. Bonne chance!

1
Joseph Weissman

Nous écrivons Daleq comme une enveloppe autour de DbUnit pour répondre à certaines des préoccupations mentionnées. Cela vous permet de remplir une base de données juste au sein de votre test unitaire plutôt que de vous fier à l'édition de fichiers XML. 

1
Lars

Moi aussi j'ai eu des problèmes similaires avec DBUnit. Surtout pour l'utiliser pour renseigner des données de développement local et exporter des données d'une base de données réelle. J'ai rencontré plusieurs cas où il exportait un jeu de données qu'il ne pouvait pas importer ensuite.

Cela m'a inspiré pour écrire une nouvelle bibliothèque pour elle: https://github.com/jeffskj/phonydata

Cela utilise un DSL groovy pour définir les jeux de données, ce qui permet une représentation très compacte des données et permet de faire des choses sympas comme générer des données aléatoires puisqu'il s'agit simplement d'un code groovy.

1
Jeff S

La situation de DBUnit est en effet parfois frustrante. Certains des problèmes sont résolus depuis Marc Philipp avec dbunit-datasetbuilder , surtout si vous le combinez avec le validator , qui est à un stade très précoce. Vous pouvez le voir en action à SZE .

Clause de non-responsabilité: Toutes les ressources github référencées sont gérées par moi.

0
niels

Je viens de publier un framework groovy basé sur DSL appelé pedal-loader disponible via github . Documentation ici .

Il vous permet de travailler directement avec l'abstraction de niveau d'entité JPA. Puisqu'il s'agit d'un script groovy, vous pouvez utiliser toutes les constructions groovy. 

Pour insérer des lignes dans une table appuyée par une entité JPA appelée Student, avec des champs (non des colonnes de base de données, mais des champs mappés) appelés id, name et grade, procédez comme suit:

allStudents = table(Student, ['id', 'name', 'grade']) {
    row 1, 'Joe', Grade.A
    rowOfInterest = row 2, 'John', Grade.B
}

Grade est une énumération de la classe Student mappée à la colonne de la base de données (peut-être en utilisant l'annotation JPA 2.1 @Convert). allStudents est une liste qui contiendra les lignes et rowOfInterest est une référence à une ligne particulière. Ces propriétés (allStudents et rowOfInterest) sont disponibles pour votre test unitaire.

0
Καrτhικ

Une alternative utilisant Spring configuration et Specs2 testing peut être trouvée ici

0
pagoda_5b