2010-03-18 4 views
9

Je l'ai googlé un peu et n'ai pas vraiment trouvé la réponse dont j'avais besoin.Unité de test d'insertion/mise à jour/suppression

Je travaille sur une page Web en C# avec SQL Server et LINQ pour un client. Je souhaite que les utilisateurs puissent envoyer des messages les uns aux autres. Donc ce que je fais, c'est que je l'ai testé avec des données qui vont dans la base de données.

Le problème est que je dépend maintenant d'avoir au moins 2 utilisateurs dont je connais l'ID. De plus, je dois nettoyer après moi-même. Cela conduit à des tests unitaires assez importants qui testent beaucoup dans un test.

Disons que je voudrais mettre à jour un utilisateur. Cela signifierait que je devrais ceate l'utilisateur, le met à jour, puis le supprime. Cela fait beaucoup d'assertions dans un test unitaire et si cela échoue avec la mise à jour, je dois le supprimer manuellement.

Si je le ferais d'une autre façon, sans enregistrer les données DB, je ne serais pas pour être sûr en mesure de savoir que les données étaient présentes dans la base de données après la mise à jour, etc.

Quelle est la bonne façon pour ce faire sans avoir un test qui teste beaucoup de fonctionnalités dans un test?

+3

"Ce que je fais, c'est que je l'ai testé avec des données en direct" C'est contradictoire. Live Data signifie que vous n'êtes pas un test unitaire, que vous effectuez des tests de convivialité, des tests de performances ou des tests d'intégration. Le test unitaire signifie «tester beaucoup de fonctionnalités par lui-même». Peut-être que vous devriez mettre à jour la question. –

+0

Merci de l'avoir signalé, quelque chose s'est mal passé dans ma tête. J'ai édité maintenant –

Répondre

17

Est-ce que tout le test à l'intérieur d'un bloc System.Transactions.TransactionScope, et tout simplement ne pas appeler Scope.Complete() ... Tous les changements seront annulés lorsque vous quittez, et les autres utilisateurs ne pourront pas voir les données temporaires que vous créez dans la base de données, donc le processus de test n'affectera que la machine de test ..

Vous peut entrer dans un nouvel utilisateur, lisez la base de données pour vérifier qu'il a été saisi correctement, et tout ce que vous devez vérifier, dans le bloc de TransactionScope ...

Avoir la méthode d'essai unique unité usurper les deux utilisateurs différents, le tout dans une transaction ...

par exemple Code

using (var scop = new System.Transactions.TransactionScope()) 
    { 
     // all your test code and Asserts that access the database, 
     // writes and reads, from any class, ... 
     // to commit at the very end of this block, 
     // you would call 
     // scop.Complete(); // ..... but don't and all will be rolled back 
    } 
+0

Ressemble à ce dont j'ai besoin. Est-ce que cela fonctionnerait comme si les données étaient dans la base de données, mais je ne commettrais pas? J'accède aux données dans certaines classes et ils devront "penser" que les données sont dans le DB –

+0

D'autres utilisateurs * pourraient être capables de le voir s'ils jouent avec le niveau d'isolation de la transaction. C'est généralement une action délibérée, cependant, donc pas vraiment de quoi s'inquiéter. – DaveE

+0

comment cela fonctionne-t-il, est-ce que les données stockées dans la base de données entre-temps ou est-il stocké dans la mémoire? –

4

dispose d'un fichier de fixtures (en XML, SQL, YAML, peu importe) que vous pouvez charger dans la base de données de test local avec juste une commande.

E.g. un fichier pour deux appareils utilisateurs qui ont besoin d'un message à l'autre peut ressembler (ceci est à moi):

Member: 

    Member_WibWobble: 
    username:  Wibble_Wobble 
    email_address: [email protected][removed].com 
    password:  pw 
    is_super_admin: true 
    last_login:  "2010-01-06 12:12:57" 
    Country:  country_AU 
    UploadImage: 
     type:   <?php echo UploadImage::TYPE_MEMBER_AVATAR."\n"; ?> 
     upload:  "http://localhost/[removed]/images/wibwobble.jpg" 

    Member_BunnyHugs: 
    username:  BunnyHugs 
    email_address: [email protected][removed].com 
    password:  pw 
    is_super_admin: true 
    last_login:  "2009-12-01 14:11:11" 
    Country:  country_UK 
    UploadImage: 
     type:   <?php echo UploadImage::TYPE_MEMBER_AVATAR."\n"; ?> 
     upload:  "http://localhost/[removed]/images/bunnyhugs.jpg" 

PrivateMessage: 

    PrivateMessage_1: 
    subject:   "Yo" 
    body:   | 
     hi 

     <b>escape this html please</b> 

     bye 
    is_read:   false 
    Sender:   Member_WibWobble 
    Recipient:  Member_BunnyHugs 
+0

C'est une bonne idée, surtout si vous utilisez SQLite sur une autre base de données basée sur la mémoire. Cela vous donnera de meilleures performances, surtout si vous voulez tester avec de grands ensembles de données. –

+0

Mais cela ne signifierait-il pas que je devrais ajouter ces données à la base de données pour les tester ..? –

+0

@Kurresmack: Oui. – NotMe

4

bases de données de tests unitaires peuvent être PITA en raison de la nature même d'entre eux (persisté stockage).

Pour ce faire, à droite, vous devez toujours commencer par un schéma vide. Ensuite, faites charger le code de test dans les valeurs de données qui doivent être présentes. Cela peut être aussi simple que d'exécuter un script sql qui contient le schéma et les données par défaut.

Une fois cela fait, commencez à exécuter vos tests. Les tests devraient englober toutes les opérations de crud que votre application fera normalement.

Si une défaillance se produit, ce n'est pas un gros problème parce que, encore une fois, vous devriez commencer à nouveau à chaque fois que toute façon.

En outre, vous souhaitez conserver ces données en cas d'environ un échec de test afin que vous puissiez vérifier l'état de base de données au moment de l'échec. Donc, c'est à la fois une bonne et une mauvaise chose.

Le long de ces lignes, les tests db doivent être exécutés sur sa propre instance de base de données de test. De cette façon, vous n'avez pas à vous soucier des problèmes transitoires comme quelqu'un qui change une structure db sous vous pendant que les tests progressent.

En fin de compte, les tests de base de données est un projet en soi.