如何:编写在单个事务范围内运行的数据库单元测试
更新:2007 年 11 月
可以修改单元测试,使其在单个事务范围内运行。如果您使用此方法,则可以在测试结束之后回滚在测试过程中执行的任何更改。下面的过程说明了具体的做法:
在使用 BEGIN TRANSACTION 和 ROLLBACK TRANSACTION 的 Transact-SQL (T-SQL) 测试脚本中创建事务。
为某个测试类中的单个测试方法创建一个事务。
为给定测试类中的所有测试方法创建一个事务。
系统必备
对于本主题中的某些过程,运行单元测试的计算机必须正在运行分布式事务协调程序服务。有关更多信息,请参见本主题末尾的过程。
使用 T-SQL 创建事务
使用 T-SQL 创建事务
在数据库单元测试设计器中打开单元测试。
指定要创建事务的脚本类型。例如,可以指定预先测试、测试或后期测试。
在 T-SQL 编辑器中输入测试脚本。
插入 BEGIN TRANSACTION 和 ROLLBACK TRANSACTION 语句,如下面的简单示例所示。此示例使用包含 50 行数据的 Northwind 数据库表:
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
说明: 在执行 COMMIT TRANSACTION 语句之后不能对事务进行回滚。
有关 ROLLBACK TRANSACTION 如何与存储过程和触发器一起使用的更多信息,请参见 Microsoft 网站 上的“ROLLBACK TRANSACTION (Transact-SQL)”。
为单个测试方法创建事务
在该示例中,在使用 TransactionScope 类型时,会使用环境事务。默认情况下,“执行连接”和“特权连接”将不使用环境事务,因为这些连接是在执行该方法之前创建的。SqlConnection 具有一个 EnlistTransaction 方法,该方法将活动连接与某个事务相关联。环境事务在创建之后会自行注册为当前的事务,您可以通过 Current 属性来访问它。在该示例中,环境事务在释放之后进行回滚。如果要提交在运行单元测试时进行的任何更改,则必须调用 Complete 方法。
为单个测试方法创建事务
打开单元测试的 Visual Basic 或 C# 文件。
包装预先测试、测试和后期测试操作,如下面的 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。还必须在这些程序集中添加对项目的引用。
为某个测试类中的所有测试方法创建一个事务
为某个测试类中的所有测试方法创建一个事务
打开单元测试的 Visual Basic 或 C# 文件。
在 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 服务
打开“控制面板”。
在“控制面板”中打开“管理工具”。
在“管理工具”中打开“服务”。
在“服务”窗格中,右击“分布式事务处理协调器”服务,再单击“启动”。
该服务的状态应当更新为“已启动”。现在应当能够运行那些使用 System.Transactions 的单元测试。