Condividi tramite


Procedura: scrivere uno unit test del database da eseguire nell'ambito di una singola transazione

Le informazioni contenute in questo argomento sono valide per:

Visual Studio Ultimate

Visual Studio Premium

Visual Studio 2010 Professional 

Visual Studio Express

Argomento applicabile Argomento applicabile Argomento non applicabile Argomento non applicabile

È possibile modificare gli unit test per eseguirli nell'ambito di una singola transazione. In questo modo è possibile eseguire il rollback delle modifiche apportate dopo l'esecuzione del test. Di seguito vengono illustrate le procedure seguenti:

  • Creare una transazione nello script di test Transact-SQL in cui si utilizzano BEGIN TRANSACTION e ROLLBACK TRANSACTION.

  • Creare una transazione per un singolo metodo di test in una classe di test.

  • Creare una transazione per tutti i metodi di test in una determinata classe di test.

Prerequisiti

Per alcune procedure in questo argomento, il servizio Distributed Transaction Coordinator deve essere in esecuzione sul computer sul quale si eseguono gli unit test. Per ulteriori informazioni, vedere la procedura alla fine di questo argomento.

Per creare una transazione mediante Transact-SQL

Per creare una transazione mediante Transact-SQL

  1. Aprire uno unit test nella finestra di progettazione unit test del database.

  2. Specificare il tipo di script per il quale creare la transazione. È ad esempio possibile specificare uno script di pre-test, di test o di post-test.

  3. Immettere uno script di test nell'editor Transact-SQL.

  4. Inserire le istruzioni BEGIN TRANSACTION e ROLLBACK TRANSACTION, come illustrato in questo semplice esempio. Nell'esempio viene utilizzata una tabella di database denominata OrderDetails che contiene 50 righe di dati:

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

    Nota

    Non è possibile ripristinare lo stato precedente di una transazione dopo l'esecuzione di un'istruzione COMMIT TRANSACTION.

    Per ulteriori informazioni sul funzionamento di ROLLBACK TRANSACTION con stored procedure e trigger, vedere la pagina corrispondente sul sito Web Microsoft ROLLBACK TRANSACTION (Transact-SQL).

Per creare una transazione per un singolo metodo di test

In questo esempio, viene utilizzata una transazione di ambiente quando si utilizza il tipo TransactionScope. Per impostazione predefinita, le connessioni privilegiate e di esecuzione non utilizzeranno la transazione di ambiente, poiché le connessioni sono state create prima che il metodo venisse eseguito. SqlConnection ha un metodo EnlistTransaction che associa una connessione attiva a una transazione. Quando viene creata una transazione di ambiente, si registra come transazione corrente ed è possibile accedervi tramite la proprietà Current. In questo esempio, la transazione viene ripristinata quando la transazione di ambiente viene eliminata. Per eseguire il commit delle modifiche effettuate durante l’esecuzione dello unit test, è necessario chiamare il metodo Complete.

Per creare una transazione per un singolo metodo di test

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Riferimenti nel progetto di test, quindi scegliere Aggiungi riferimento.

    Verrà visualizzata la finestra di dialogo Aggiungi riferimento.

  2. Fare clic sulla scheda .NET.

  3. Nell'elenco di assembly fare clic su System.Transactions, quindi fare clic su OK.

  4. Aprire il file Visual Basic o C# per lo unit test.

  5. Incapsulare le azioni di pre-test, di test e di post-test come illustrato nell'esempio di codice Visual Basic seguente:

        <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
    

    Nota

    Se si utilizza Visual Basic, è necessario aggiungere Imports System.Transactions, oltre a Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting e Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions. Se si utilizza Visual C#, è necessario aggiungere using System.Transactions, oltre alle istruzioni using per Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting e Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions. È inoltre necessario aggiungere a tali assembly un riferimento al progetto.

Per creare una transazione per tutti i metodi di test in una classe di test

Per creare una transazione per tutti i metodi di test in una classe di test

  1. Aprire il file Visual Basic o C# per lo unit test.

  2. Creare la transazione in TestInitialize ed eliminarla in TestCleanup, come illustrato nell'esempio di codice Visual C# seguente:

    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);
    
            }
    

Per avviare il servizio Distributed Transaction Coordinator

Alcune procedure in questo argomento utilizzano i tipi contenuti nell'assembly System.Transactions. Prima di eseguire queste procedure, è necessario assicurarsi che il servizio Distributed Transaction Coordinator sia in esecuzione sul computer dove si eseguono gli unit test. In caso contrario, i test avranno esito negativo e verrà visualizzato il seguente messaggio di errore: "Metodo di test NomeProgetto.NomeTest.NomeMetodo ha generato l’eccezione: System.Data.SqlClient.SqlException: MSDTC sul server 'NomeComputer' non è disponible".

Per avviare il servizio Distributed Transaction Coordinator

  1. Aprire il Pannello di controllo.

  2. Aprire Strumenti di amministrazione nel Pannello di controllo.

  3. In Strumenti di amministrazione aprire Servizi.

  4. Nel riquadro Servizi fare clic con il pulsante destro del mouse su Distributed Transaction Coordinator e scegliere Avvia.

    Lo stato del servizio verrà aggiornato ad Avviato. Sarà ora possibile eseguire unit test con System.Transactions.

Nota importanteImportante

Potrebbe venire visualizzato l'errore seguente, anche se si è avviato il servizio 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). Se viene visualizzato questo errore, è necessario configurare Distributed Transaction Coordinator per l'accesso di rete. Per ulteriori informazioni, vedere la pagina relativa all'abilitazione dell'accesso di rete DTC.