如何:编写在单个事务范围内运行的数据库单元测试

本主题适用于:

Visual Studio 旗舰版

Visual Studio 高级专业版

Visual Studio 2010 专业版 

Visual Studio 学习版

主题适用 主题适用 主题不适用 主题不适用

可以修改单元测试,使其在单个事务范围内运行。 如果您使用此方法,则可以在测试结束之后回滚在测试过程中执行的任何更改。 下面的过程说明了具体的做法:

  • 在使用 BEGIN TRANSACTION 和 ROLLBACK TRANSACTION 的 Transact-SQL 测试脚本中创建事务。

  • 为某个测试类中的单个测试方法创建一个事务。

  • 为给定测试类中的所有测试方法创建一个事务。

系统必备组件

对于本主题中的某些过程,运行单元测试的计算机必须正在运行 Distributed Transaction Coordinator 服务。 有关更多信息,请参见本主题末尾的过程。

使用 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 如何与存储过程和触发器一起使用的更多信息,请参见 Microsoft 网站上的 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
    

    提示

    如果使用的是 Visual Basic,则除了 Imports Microsoft.VisualStudio.TestTools.UnitTesting、Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 和 Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions,还必须添加 Imports System.Transactions。如果使用的是 Visual C#,则除了 Microsoft.VisualStudio.TestTools、Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 和 Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions 的 using 语句,还必须添加 using System.Transactions。 还必须在这些程序集中添加对项目的引用。

为某个测试类中的所有测试方法创建一个事务

为某个测试类中的所有测试方法创建一个事务

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

启动 Distributed Transaction Coordinator 服务

本主题中的某些过程使用 System.Transactions 程序集内的类型。 在按照这些过程操作之前,必须确保要运行单元测试的计算机上正在运行 Distributed Transaction Coordinator 服务。 否则,测试将失败,并出现下面的错误消息:“测试方法 项目名称.测试名称.方法名称 引发异常: System.Data.SqlClient.SqlException: 服务器‘计算机名称’上的 MSDTC 不可用”。

启动 Distributed Transaction Coordinator 服务

  1. 打开**“控制面板”**。

  2. 在**“控制面板”中打开“管理工具”**。

  3. 在**“管理工具”中打开“服务”**。

  4. 在**“服务”窗格中,右击 “Distributed Transaction Coordinator” 服务,再单击“启动”**。

    该服务的状态应当更新为**“已启动”**。 现在应当能够运行那些使用 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 访问