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

 

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

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

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

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

Предварительные требования

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

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

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

  1. Откройте модульный тест в конструкторе модульных тестов SQL Server.(Дважды щелкните файл исходного кода, чтобы открыть модульный тест в конструкторе.)

  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
    
    System_CAPS_noteПримечание

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

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

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

В этом примере при использовании типа TransactionScope будет задействована внешняя транзакция.По умолчанию соединения для выполнения и привилегированные подключения не используют внешнюю транзакцию, так как они создаются до выполнения этого метода.Соединение 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
    
    System_CAPS_noteПримечание

    Если используется 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.При запуске модульных тестов, прежде чем выполнять эти процедуры, необходимо убедиться в том, что служба координатора распределенных транзакций запущена на компьютере.В противном случае тесты будут завершаться следующей ошибкой: «Метод теста ProjectName.TestName.MethodName вызвал исключение: System.Data.SqlClient.SqlException: MSDTC на сервере ComputerName недоступен».

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

  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.

См. также

Создание и определение модульных тестов SQL Server