Partager via


Comment : écrire un test unitaire de base de données qui s'exécute dans la portée d'une transaction unique

Cette rubrique s'applique à :

Visual Studio Ultimate

Visual Studio Premium

Visual Studio 2010 Professional 

Visual Studio Express

La rubrique s'applique La rubrique s'applique La rubrique ne s'applique pas La rubrique ne s'applique pas

Vous pouvez modifier des tests unitaires pour qu'ils s'exécutent dans la portée d'une transaction unique. Si vous adoptez cette approche, vous pouvez restaurer toutes modifications activées par le test après la fin du test. Les procédures suivantes expliquent comment :

  • Créer une transaction dans votre script de test Transact-SQL qui utilise BEGIN TRANSACTION et ROLLBACK TRANSACTION.

  • Créer une transaction pour une méthode de test unique dans une classe de test.

  • Créer une transaction pour toutes les méthodes de test dans une classe de test donnée.

Composants requis

Pour certaines procédures de cette rubrique, le service Distributed Transaction Coordinator doit s'exécuter sur l'ordinateur où vous exécutez des tests unitaires. Pour plus d'informations, consultez la procédure en fin de rubrique.

Pour créer une transaction à l'aide de Transact-SQL

Pour créer une transaction à l'aide de Transact-SQL

  1. Ouvrez un test unitaire dans le Concepteur de test unitaire de base de données.

  2. Spécifiez le type de script pour lequel vous voulez créer la transaction. Par exemple, vous pouvez spécifier un script de prétest, de test ou de post-test.

  3. Entrez un script de test dans l'éditeur Transact-SQL.

  4. Insérez des instructions BEGIN TRANSACTION et ROLLBACK TRANSACTION, comme indiqué dans l'exemple simple suivant. L'exemple utilise une table de base de données nommée OrderDetails qui contient 50 lignes de données :

    BEGIN TRANSACTION TestTransaction
    UPDATE "OrderDetails" set Quantity = Quantity + 10
    IF @@ROWCOUNT!=50
    RAISERROR('Row count does not equal 50',16,1)
    ROLLBACK TRANSACTION TestTransaction
    

    Notes

    Vous ne pouvez pas restaurer une transaction après l'exécution d'une instruction COMMIT TRANSACTION.

    Pour plus d'informations sur l'utilisation de ROLLBACK TRANSACTION avec les procédures stockées et les déclencheurs, consultez cette page du site Web Microsoft : ROLLBACK TRANSACTION (Transact-SQL).

Pour créer une transaction pour une méthode de test unique

Dans cet exemple, vous utilisez une transaction ambiante avec le type TransactionScope. Par défaut, les connexions d'exécution et les connexions privilégiées n'utiliseront pas la transaction ambiante, parce qu'elles ont été créées avant que la méthode ne soit exécutée. L'objet SqlConnection a une méthode EnlistTransaction qui associe une connexion active à une transaction. Lorsqu'une transaction ambiante est créée, elle s'enregistre comme transaction en cours, et vous pouvez y accéder via la propriété Current. Dans cet exemple, la transaction est restaurée lorsque la transaction ambiante est supprimée. Si vous souhaitez valider toutes les modifications qui ont été apportées lorsque vous avez exécuté le test unitaire, vous devez appeler la méthode Complete.

Pour créer une transaction pour une méthode de test unique

  1. Dans l' Explorateur de solutions, cliquez avec le bouton droit sur le nœud Références de votre projet de test et cliquez sur Ajouter une référence.

    La boîte de dialogue Ajouter une référence s'affiche.

  2. Cliquez sur l'onglet .NET.

  3. Dans la liste d'assemblys, cliquez sur System.Transactions puis sur OK.

  4. Ouvrez le fichier Visual Basic ou C# pour votre test unitaire.

  5. Encapsulez les actions de prétest, de test et de post-test, comme indiqué dans l'exemple de code Visual Basic suivant :

        <TestMethod()> _
        Public Sub dbo_InsertTable1Test()
    
            Using ts as New System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required)
                ExecutionContext.Connection.EnlistTransaction(Transaction.Current)
                PrivilegedContext.Connection.EnlistTransaction(Transaction.Current)
    
                Dim testActions As DatabaseTestActions = Me.dbo_InsertTable1TestData
                'Execute the pre-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PretestAction) Is Nothing), "Executing pre-test script...")
                Dim pretestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PretestAction)
                'Execute the test script
    
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.TestAction) Is Nothing), "Executing test script...")
                Dim testResults() As ExecutionResult = TestService.Execute(ExecutionContext, Me.PrivilegedContext, testActions.TestAction)
    
                'Execute the post-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PosttestAction) Is Nothing), "Executing post-test script...")
                Dim posttestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PosttestAction)
    
                'Because the transaction is not explicitly committed, it
                'is rolled back when the ambient transaction is 
                'disposed.
                'To commit the transaction, remove the comment delimiter
                'from the following statement:
                'ts.Complete()
    
        End Sub
        Private dbo_InsertTable1TestData As DatabaseTestActions
    

    Notes

    Si vous utilisez Visual Basic, vous devez ajouter Imports System.Transactions (en plus de Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting et Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions). Si vous utilisez Visual C#, vous devez ajouter using System.Transactions (en plus des instructions using pour Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting, and Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions). Vous devez également ajouter une référence à votre projet dans ces assemblys.

Pour créer une transaction pour toutes les méthodes de test dans une classe de test

Pour créer une transaction pour toutes les méthodes de test dans une classe de test

  1. Ouvrez le fichier Visual Basic ou C# pour votre test unitaire.

  2. Créez la transaction dans TestInitialize, puis supprimez-la dans TestCleanup, comme indiqué dans l'exemple de code Visual C# suivant :

    TransactionScope _trans;
    
            [TestInitialize()]
            public void Init()
            {
                _trans = new TransactionScope();
                base.InitializeTest();
            }
    
            [TestCleanup()]
            public void Cleanup()
            {
                base.CleanupTest();
                _trans.Dispose();
            }
    
            [TestMethod()]
            public void TransactedTest()
            {
                DatabaseTestActions testActions = this.DatabaseTestMethod1Data;
                // Execute the pre-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PretestAction != null), "Executing pre-test script...");
                ExecutionResult[] pretestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PretestAction);
                // Execute the test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.TestAction != null), "Executing test script...");
                ExecutionResult[] testResults = TestService.Execute(this.ExecutionContext, this.PrivilegedContext, testActions.TestAction);
                // Execute the post-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PosttestAction != null), "Executing post-test script...");
                ExecutionResult[] posttestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PosttestAction);
    
            }
    

Pour démarrer le service Distributed Transaction Coordinator

Certaines procédures de cette rubrique utilisent des types de l'assembly System.Transactions. Avant de suivre ces procédures, vous devez vous assurer que le service Distributed Transaction Coordinator s'exécute sur l'ordinateur où vous exécutez les tests unitaires. Sinon, les tests échouent et le message d'erreur suivant apparaît : "La méthode de test NomProjet.NomTest.NomMéthode a levé l'exception System.Data.SqlClient.SqlException : MSDTC sur le serveur 'NomOrdinateur' n'est pas disponible"

Pour démarrer le service Distributed Transaction Coordinator

  1. Ouvrez le Panneau de configuration.

  2. Dans le Panneau de configuration, ouvrez Outils d'administration.

  3. Dans Outils d'administration, ouvrez les Services.

  4. Dans le volet Services, cliquez avec le bouton droit sur le service Distributed Transaction Coordinator et cliquez sur Démarrer.

    L'état du service doit passer à Démarré. Vous devez maintenant être en mesure d'exécuter des tests unitaires qui utilisent System.Transactions.

Important

L'erreur suivante peut s'afficher, même si vous avez démarré le service Distributed Transaction Coordinator : System.Transactions.TransactionManagerCommunicationException: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool. ---> System.Runtime.InteropServices.COMException: The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024). Si cette erreur s'affiche, vous devez configurer le service Distributed Transaction Controller pour l'accès réseau. Pour plus d'informations, consultez Activation de l'accès DTC réseau.