Comment : écrire un test unitaire de base de données qui s'exécute dans la portée d'une transaction unique
Mise à jour : novembre 2007
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 (T-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 T-SQL
Pour créer une transaction à l'aide de T-SQL
Ouvrez un test unitaire dans le Concepteur de test unitaire de base de données.
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.
Entrez un script de test dans l'éditeur T-SQL.
Insérez des instructions BEGIN TRANSACTION et ROLLBACK TRANSACTION, comme indiqué dans l'exemple simple suivant. Cet exemple utilise la table de la base de données Northwind, qui contient 50 lignes de données :
BEGIN TRANSACTION TestTransaction UPDATE "Order Details" set Quantity = Quantity + 10 IF @@ROWCOUNT!=50 RAISERROR('Row count does not equal 50',16,1) ROLLBACK TRANSACTION TestTransaction
Remarque : Vous ne pouvez pas restaurer une transaction après l'exécution d'une instruction COMMIT TRANSACTION.
Pour plus d'informations sur le fonctionnement de ROLLBACK TRANSACTION avec des procédures stockées et des déclencheurs, consultez « ROLLBACK TRANSACTION (Transact-SQL) » sur le site Web Microsoft.
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
Ouvrez le fichier Visual Basic ou C# pour votre test unitaire.
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
Remarque : 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 et 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
Ouvrez le fichier Visual Basic ou C# pour votre test unitaire.
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
Ouvrez le Panneau de configuration.
Dans le Panneau de configuration, ouvrez Outils d'administration.
Dans Outils d'administration, ouvrez les Services.
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.