IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

Comment testez-vous vos couches d’accès aux données (DAL) ?


Sujet :

Dotnet

  1. #1
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut Comment testez-vous vos couches d’accès aux données (DAL) ?
    je reprends l'idée d'un billet que j'ai publié récemment afin de receuillir vos expériences.

    C'est toujours difficile de tester sa DAL, j'ai trouvé plusieurs méthodes :

    Ajouter, supprimer manuellement les données qui ont pu être supprimées, ajoutées à chaque test. Cela nécessite d'exécuter du sql en vrac à chaque test et peut être un travail laborieux et décourager le développeur quand les données sont nombreuses.

    Restaurer un dump de la base de données de test après chaque exécution du test. Cela est très problématique si la base de données est volumineuse.

    Avoir un moyen de mettre une base de données de test dans un certain état à chaque début de test (Unit Testing the Data Access Layer, par Tim Stall, Get Test Infected with NUnit: Unit Test Your .NET Data Access Layer, par Steven A. Smith). Cela nécessite un gros travail pour mettre sa base en état (construction de script sql pour vider la base, construire la structure, ajouter les données, etc ...) et un temps non négligeable d'exécution à chaque test. Cela peut aussi être gênant lorsqu'on travaille à plusieurs sur la même base de test.

    Avoir une base de données de test et exécuter chaque opération CRUD dans une transaction qui sera ensuite annulée. Cela nécessite de rajouter du code spécifique dans nos tests pour créer et annuler la transaction.

    Utiliser COM+ entreprise services (ou COM+ 1.5) et utiliser une classe de base pour ses tests qui encapsule la création et l'annulation de la transaction (Simplify Data Layer Unit Testing using Enterprise Services de Roy Osherove). Cela nécessite d'avoir un provider ADO.NET qui supporte les transactions distribuées, ce qui est quand même le cas de bon nombre d'entre eux et nécessite d'exécuter que des commandes sql qui peuvent être utilisées dans une transaction distribuée.

    Des frameworks de test (MbUnit, XtUnit, NunitX) semblent utiliser des attributs à poser sur ses tests pour effectuer la restauration des données altérées)

    Et vous, comment testez-vous vos DAL ?
    Avez vous testé l'une de ces méthodes ? Quels sont vos retour d'expérience ?

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Tiens c'était justement la question de la réunion d'équipe aujourd'hui ... Ca tombe bien

  3. #3
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    et qu'avez vous répondu alors ?

  4. #4
    Membre chevronné Avatar de LooserBoy
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2005
    Messages : 1 085
    Points : 1 976
    Points
    1 976
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    Et vous, comment testez-vous vos DAL ?
    Avez vous testé l'une de ces méthodes ? Quels sont vos retour d'expérience ?
    En ce qui me concerne, deux méthodes ont été utilisées:
    - Restauration d'une base "propre" avant chaque test. Effectivement, cela est problématique avec une volumétrie importante. On avait limité le problème en ayant une base de test allégée en données (à 0% de matières grasses ).

    - Mettre la base de test partagée par l'équipe dans un état prédéterminé par script SQL pour se simplifier la tâche. C'est la méthode utilisée dans ma mission actuelle. On se "télescope" énormément entre nous. Mais compte tenu de la volumétrie très importante, on a pas mieux à proposer pour le moment.
    Vu sur un paquet de cigarettes: "Fumer peut entrainer une mort lente et douloureuse"
    - Vivre aussi... Ce n'est pas forcément moins douloureux et c'est même beaucoup plus lent...

  5. #5
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    J'ai expérimenté lors de récents projets une structure qui fonctionne pas mal :

    Branchement de la DAL sur une base en mémoire (style SQLite) lorsqu'on est dans un contexte de tests.

    Génération du schéma de base (ça se fait facilement avec un ORM comme NHibernate) et remplissage des données minimales à chaque lancement de testFixture.

    Après chaque test, rollback des modifications faites par le test.

    Au niveau perfs, la différence par rapport à un "vrai" SGBD sur le poste du développeur, et d'autant plus par rapport à une base mutualisée, est assez significative.

    Toutefois le temps d'exécution de ce genre de test reste tout de même élevé pour un projet conséquent, c'est pourquoi je pense qu'il faut essayer de limiter au maximum les tests unitaires qui interagissent avec la base de données. C'est d'autant plus vrai dans un contexte d'intégration continue ou les tests sont joués très régulièrement.
    Pensez au bouton

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 49
    Points : 91
    Points
    91
    Par défaut
    Pour ma part, avec une base Firebird:
    - la dll de test unitaires utilise Firebird Embedded, ce qui évite d'avoir besoin de firebird sur le serveur ou le poste de test, ou de gérer des bases de test pour plusieurs développeurs
    - pour chaque test le nécessitant, une copie de base vide de données (avec firebird c'est un fichier) est faite et un script d'insertion de données est exécuté.
    Cela permet aussi d'avoir les scripts des données de tests dans subversion par exemple et voir l'historique des modifications.

    Cette façon de faire ne ralentit pas de façon notable l'exécution des tests, mais nous n'avons pas une énorme base avec genre 400 tables, et le jeu de données inséré à chaque fois est celui minimum pour la réussite d'un petit ensemble de Tests.
    D'un autre coté, un base de test pour les test unitaires ne devrait pas être volumineuse ? (on ne teste pas les performances.)

    Edit :
    ah, c'est exactement la solution déconseillée par Maximilian

  7. #7
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par Plageman Voir le message
    ah, c'est exactement la solution déconseillée par Maximilian
    Heu, je ne la déconseille pas, c'est un mal nécessaire De toute façon, pour tester la DAL (ce qui est le sujet original du thread) on ne peut pas y couper.

    Simplement un test unitaire qui n'a pas pour objet l'accès aux données lui-même devrait autant que faire se peut éviter toute dépendance à la couche d'accès aux données. Sinon il n'est plus vraiment unitaire, ça devient un test d'intégration.

    Easy to Setup

    How easily can I set up an environment to run the tests? If the answer is "not very," I might never get the tests running. As much as possible, decouple unit tests from external dependencies like databases and web services by using mocks or stubs. When you do test against an external dependency, the dependency better be setup correctly by the automated build.
    http://codebetter.com/blogs/jeremy.m...20/129552.aspx
    Pensez au bouton

  8. #8
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 29
    Points : 52
    Points
    52
    Par défaut Nettoyage de BD
    Bonjour,
    Moi personnellement je programme depuis 1981 et avec les années, j'ai peaufiné une technique qui consiste a exéctuer une routine de testes à chaque lancement de l'application qui va mettoyer toutes les tables de la BD qui subissent des mouvements (insertion, update et delete), et ca fonctionne très très bien depuis une dizaine d'années maintenant.

  9. #9
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Points : 1 640
    Points
    1 640
    Par défaut
    En Java il existe une api, dbunit, qui sert justement à réaliser des tests unitaires et d'intégration pour les couches d'accès aux données. Peut-être en existe-t-il un équivalent pour .Net ?
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 57
    Points : 68
    Points
    68
    Par défaut
    Dans notre entreprise nous utlisons NDbUnit pour cela.

    Baké Jc. BAKENEGHE
    Sofware Coordinator
    http://koossery-tech.fr

  11. #11
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    Utiliser COM+ entreprise services (ou COM+ 1.5) et utiliser une classe de base pour ses tests qui encapsule la création et l'annulation de la transaction (Simplify Data Layer Unit Testing using Enterprise Services de Roy Osherove). Cela nécessite d'avoir un provider ADO.NET qui supporte les transactions distribuées, ce qui est quand même le cas de bon nombre d'entre eux et nécessite d'exécuter que des commandes sql qui peuvent être utilisées dans une transaction distribuée.
    Pour ma part, j'ai testé cette solution qui est plutot efficace et pas trop compliqué à mettre en place.

    Cette solution a quand même un gros inconvénient, c'est que pendant son temps d'exécution, elle bloque toutes les requetes select qui n'ont pas de (nolock), ou les insert/update. Et ceci pour tous les autres utilisateurs également. (sql server)

  12. #12
    En attente de confirmation mail

    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 766
    Points : 1 267
    Points
    1 267
    Par défaut
    Avoir une base de données de test et exécuter chaque opération CRUD dans une transaction qui sera ensuite annulée. Cela nécessite de rajouter du code spécifique dans nos tests pour créer et annuler la transaction.
    Et quand il y a un problème, je rebascule une bdd propre. L'avantage est qu'on peut tester les effets de bord : un test A se passe mal, mais n'est pas détecté. Le test B suppose que tout était comme avant, mais ce qu'a engendré A fait planter B.

    Bonjour le casse-tête pour trouver que c'est A le responsable. On corrige, on rajoute le test d'effet de bord qui aurait du être fait dans A et on repart au combat.

  13. #13
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    quels sont les outils que vous utilisez pour remettre en état vos bases de données ?

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    et qu'avez vous répondu alors ?
    Bah justement pas grand chose ... d'où l'intérêt que j'ai à suivre ce post.

    Disons que nous utilisons JUnit sur nos couches DAO (Hibernate). Mais nous développons plusieurs versions en parallèles, les structure des tables changent régulièrement et nous courrons un peu ces temps ci alors ... la classique gestion du temps (c'est de l'argent) ... et nos tests ne sont plus cohérents avec la/les bases.

    Actuellement 100% de nos tests automatisés sont en échec et aucune ressource n'est dispo pour mettre à jour les classes de tests.

    sinon vu l'instabilité des bases du client sur certaines couches, je pencherais pour une restauration de données spécifiques aux tests de chaque versions ... mais la base est très volumineuse et les avenants durant les phases de développements et jusqu'à la livraison sont réguliers (sans parler du manque de place à stocker les dumps)

    Bref ... pas vraiment de réponse adaptée ...

    Question subsidiaire : quels sont les apports de DBUnit par rapport à JUnit ?

  15. #15
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Ok, j'arrive un peu tard...

    Pour les tests qui tapent la Db, on a une db de test, qui n'est accédée que par le serveur díntegration continue pour les tests d'integration. Les tests unitaires ne tapent pas la db.

    Dans le projet courant, ca ne pose pas trop de pb de ne faire les tests d'integration que depuis le serveur d'integration continue, ils tournent tous les soirs, et une modif dans la base de dev doit etre reportee dans la base de test.
    Avant de fair tourner les tests, on a une tache qui fait un backup de la bdd, et apres le test, un restore de la bdd..

    Comme la base est (relativement) stable et que l'équipe est petite, ca passe...

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  16. #16
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    Citation Envoyé par Philippe Vialatte Voir le message
    Avant de fair tourner les tests, on a une tache qui fait un backup de la bdd, et apres le test, un restore de la bdd..
    Tu utilises un outil pour ca ?

    Citation Envoyé par tyzef
    les structure des tables changent régulièrement
    C'est vrai que c'est toujours un peu galère de maintenir différentes structures, avec une base de dev qui peut être facilement perturbée et une base de test qui ne reflete pas forcément la dev à un instant T

  17. #17
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Tu utilises un outil pour ca ?
    Nant + une tache custom

    http://weblogs.sqlteam.com/billg/arc...restoredb.aspx

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par Philippe Vialatte Voir le message
    Pour les tests qui tapent la Db, on a une db de test, qui n'est accédée que par le serveur díntegration continue pour les tests d'integration. Les tests unitaires ne tapent pas la db.

    Dans le projet courant, ca ne pose pas trop de pb de ne faire les tests d'integration que depuis le serveur d'integration continue, ils tournent tous les soirs, et une modif dans la base de dev doit etre reportee dans la base de test.
    Avant de fair tourner les tests, on a une tache qui fait un backup de la bdd, et apres le test, un restore de la bdd..
    Pareil, sauf qu'au lieu d'un backup/restore, il y a un script de création de la structure de la base et un autre pour insérer les données de référence (le minimum vital pour que la base soit utilisable quoi). NAnt aussi.
    L'utilisation d'un script pour la structure a un avantage en parallèle qui est d'historiser l'évolution de la structure en permettant d'utiliser des outils comme SQLCompare pour synchroniser ces évolutions vers la base de qualif/préprod/production sans avoir à tout faire à la main.

    Les tests d'intégration sont dans un projet séparé et sont lancés par le serveur d'intégration à intervalle régulier (toutes les 4h pour le moment), sur une base dédiée, recréée pour l'occasion. Ils sont exécutables aussi sur les postes de développeurs, du moment qu'ils ont au moins un SQLServer Express en local. Pour eux, il y a un 'test' explicite qui se charge de recréer la base de test en local, quand la structure ou que les données de référence changent, histoire que tout puisse se faire directement depuis VS.

    Toutes les classes de test correspondantes dérivent d'une même base qui ouvre une transaction dans le [SetUp] et fait un rollback dans le [TearDown]. La classe de base expose un dérivé de l'UnitOfWork normal pour prendre la main sur la gestion des transactions, comme ça c'est transparent pour le reste.

    Vu que les tests d'intégration sont limités à l'exécution des requêtes elles-mêmes (les Repositories concrets utilisant NHibernate), les tests restent généralement très simples. Dès qu'il s'agit de tester autre chose qu'un Repository, ça se fait via des tests unitaires normaux avec de faux repositories, sans dépendance sur NHibernate.

    L'option SQLite pourrait être plus rapide et permettre éventuellement de lancer les tests d'accès en même temps que les tests unitaires, mais j'aime autant qu'ils s'exécutent sur une plate-forme la plus proche possible de l'appli en prod :)

    Pas essayé NDbUnit, mais ça me semble un peu de l'overkill quand on a déjà ce qu'il faut pour créer une base de test, que le mécanisme de transaction est facilement utilisable et qu'on a des repositories dispos pour insérer facilement les données de test à la demande.

    (au final, merci DDD et NHibernate :)
    Be wary of strong drink.
    It can make you shoot at tax collectors, and miss.

  19. #19
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    est-ce que vous avez déjà envisagé d'utiliser Visual Studio Database edition ?

  20. #20
    Expert éminent
    Avatar de Immobilis
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    6 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 559
    Points : 9 506
    Points
    9 506
    Par défaut
    Salut,

    Pour ce qui est de tester la DAL, j'ai une architecture 3-Tiers assez robuste. Du coup il suffit de suivre le modèle et ça roule. En plus de la DAL, j'ai un objet de connexion assez pratique. Je teste toujours sur la même base sans la remettre en l'état. Elle est trop grosse.

    Il ne me semble pas qu'il y ait 36 façons d'implémenter le CRUD. Au final, les requêtes sont les mêmes. Si on utilise des procédures stockées, qu'on utilise pas trop de connections, des DataReader plutôt que des DataSet, ne pas poser de verrous sur les SELECT (sauf si nécessaire)... Un CRUD peut être testé sur une table simple. Une fois qu'il fonctionne bien cela dépend de l'architecture de la base, des modèles qu'elle représente. Certaines des tables de notre base contiennent plus de 250 champs! On ne pouvait pas aller au delà sous SQL Server 2000

    Les tests qui m'ont permis d'atteindre le niveau de performance souhaité on tourné autour des compteurs de performance de windows des serveur IIS et SQL.

    Ensuite c'est du bon sens, ne charger que les données dont on a besoin. L'architecture de la base a aussi un role à jouer (index, etc).

    A+
    "Winter is coming" (ma nouvelle page d'accueil)

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/07/2013, 13h58
  2. Comment testez-vous vos entités en JPA ?
    Par fisico dans le forum JPA
    Réponses: 16
    Dernier message: 25/11/2011, 08h42
  3. Comment testez-vous vos algos de traitement d'image ?
    Par progfou dans le forum Traitement d'images
    Réponses: 8
    Dernier message: 10/09/2007, 19h12
  4. [DAO] Programmer une couche d’accès aux données (dot.net)
    Par Promeneur dans le forum Autres
    Réponses: 8
    Dernier message: 20/03/2007, 14h50
  5. [tomcat][jsp] Comment gerez vous vos connexions bdd?
    Par olive.m dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 21/06/2004, 17h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo