Поделиться через


Практическое руководство. Написание модульного теста базы данных и тестовых запусков в области одной транзакции

Этот раздел применим к:

Visual Studio Ultimate

Visual Studio Premium

Visual Studio 2010 Professional 

Visual Studio Express

Тема применяется Тема применяется Тема не применяется Тема не применяется

Можно изменить модульные тесты, чтобы запускать их в области одной транзакции. Если принять такой подход, то по завершении теста можно выполнять откат любых внесенных им изменений. В следующих процедурах поясняется, как выполнить указанные ниже задачи.

  • Создание транзакции в скрипте теста Transact-SQL, использующем BEGIN TRANSACTION и ROLLBACK TRANSACTION.

  • Создание транзакции для одного метода теста в тестовом классе.

  • Создание транзакции для всех методов теста в определенном тестовом классе.

Необходимые условия

Для некоторых описанных в этом разделе процедур на компьютере, где выполняются модульные тесты, должна выполняться служба координатора распределенных транзакций. Дополнительные сведения см. в описании процедуры, приведенном в конце этого раздела.

Создание транзакции с помощью Transact-SQL

Создание транзакции с помощью Transact-SQL

  1. Откройте модульный тест в конструкторе модульных тестов базы данных.

  2. Укажите тип скрипта, для которого требуется создать транзакцию. Например, можно задать скрипт, выполняемый перед тестированием, скрипт тестирования и скрипт, выполняемый после тестирования.

  3. Введите скрипт теста в редакторе Transact-SQL.

  4. Вставьте инструкции BEGIN TRANSACTION иROLLBACK TRANSACTION, как показано в этом простом примере. В этом примере используется таблица базы данных с именем OrderDetails, содержащая 50 строк данных:

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

    Примечание

    Нельзя выполнить откат транзакции после выполнения инструкции COMMIT TRANSACTION.

    Дополнительные сведения о принципах работы ROLLBACK TRANSACTION с хранимыми процедурами и триггерами см. на этой странице на веб-сайте Майкрософт ROLLBACK TRANSACTION (Transact-SQL).

Создание транзакции для одного метода теста

В этом примере при использовании типа TransactionScope используется охватывающая транзакция. По умолчанию подключения Execution и Privileged для охватывающей транзакции не используются, поскольку эти подключения были созданы до выполнения данного метода. Класс SqlConnection имеет метод EnlistTransaction, связывающий активное подключение с транзакцией. При создании охватывающей транзакции она регистрирует себя как текущая транзакции и к ней можно получить доступ посредством свойства Current. В данном примере при удалении охватывающей транзакции выполняется откат данной транзакции. Если требуется сохранить изменения, внесенные в ходе выполнения модульного теста, необходимо вызвать метод Complete.

Создание транзакции для одного метода теста

  1. В обозревателе решений щелкните правой кнопкой мыши узел Ссылки в тестовом проекте и выберите команду Добавить ссылку.

    Откроется диалоговое окно Добавление ссылки.

  2. Перейдите на вкладку .NET.

  3. В списке сборок выберите System.Transactions и нажмите кнопку ОК.

  4. Откройте файл Visual Basic или C# для данного модульного теста.

  5. Заключите в оболочку действия, выполняемые до, во время и после тестирования, как показано в следующем примере кода Visual Basic:

        <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
    

    Примечание

    При использовании Visual Basic необходимо добавить Imports System.Transactions (в дополнение к Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting и Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions). При использовании Visual C# следует добавить using System.Transactions (в дополнение к операторам using для Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting и Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions).Также необходимо добавить в эти сборки ссылку на свой проект.

Создание транзакции для всех методов теста в тестовом классе

Создание транзакции для всех методов теста в тестовом классе

  1. Откройте файл Visual Basic или C# для данного модульного теста.

  2. Создайте транзакцию в TestInitialize и удалите ее в TestCleanup, как показано в следующем примере кода Visual C#.

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

Запуск службы координатора распределенных транзакций

В некоторых из описанных в этом разделе процедур используются типы из сборки System.Transactions. Перед выполнением этих процедур необходимо убедиться, что служба координатора распределенных транзакций выполняется на том компьютере, где запускаются модульные тесты. Иначе тесты завершатся неудачей и будет выведено следующее сообщение об ошибке: "Метод теста имяПроекта.имяТеста.имяМетода выбросил исключение: System.Data.SqlClient.SqlException: MSDTC на сервере 'имяКомпьютере' недоступен".

Запуск службы координатора распределенных транзакций

  1. Откройте панель управления.

  2. В панели управления откройте Администрирование.

  3. В приложении Администрирование откройте Службы.

  4. На панели Службы щелкните правой кнопкой мыши службу Координатор распределенных транзакций и выберите команду Запуск.

    Состояние службы должно измениться на Работает. Теперь можно запускать модульные тесты, использующие System.Transactions.

Важно!

Следующая ошибка может возникнуть даже если служба координатора распределенных транзакций запущена: 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).Если возникает эта ошибка, необходимо настроить службу координатора распределенных транзакций для доступа к сети.Дополнительные сведения см. в разделе Включение сетевого доступа DTC.