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

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

如果您使用此方法,则可以在测试结束之后回滚在测试过程中执行的任何更改。下面的过程说明了具体的做法:在使用 BEGIN TRANSACTION 和ROLLBACK TRANSACTION 的Transact-SQL 测试脚本中创建事务。为某个测试类中的单个测试方法创建一个事务。为给定测试类中的所有测试方法创建一个事务。系统必备组件对于本主题中的某些过程,运行单元测试的计算机必须正在运行 Distributed Transaction Coordinator 服务。有关更多信息,请参见本主题末尾的过程。使用Transact-SQL 创建事务使用Transact-SQL 创建事务在数据库单元测试设计器中打开单元测试。指定要创建事务的脚本类型。例如,可以指定预先测试、测试或后期测试。在Transact-SQL 编辑器中输入测试脚本。插入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 方法。为单个测试方法创建事务在“解决方案资源管理器”中,右击测试项目中的“引用”节点,然后单击“添加引用”。将显示"添加引用"对话框。单击“.NET”选项卡。在程序集列表中,单击“System.Transactions”,然后单击“确定”。打开单元测试的 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 服务打开“控制面板”。在“控制面板”中打开“管理工具”。在“管理工具”中打开“服务”。在“服务”窗格中,右击 “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 访问 。

谢谢楼上的兄弟,其实各个阶段的数据库测试重点,还真的很难分的很清楚。我想单元测试可能更注重各个模块对数据库 *** 作功能的实现和正确性;而集成则更多考虑,并发时对数据库 *** 作正确性和数据完整性之类的东西吧。

可能是51出来的人都太重理论了吧。我现在做测试,只要一遇到缺乏理论支持的东西,就开始反糊涂。其实很多东西,根本就没法用一个统一的理论去描述~~

用模拟测试比较的好,如果用数据库数据测试的话,那还要依赖对数据库的维护,这样不是很利于单元测试,一般来说用mock就好了,但是相对数据测试来说可能写法麻烦点。我们以前就是在数据库上测试,但是经过实践之后还是觉得用模拟数据测试比较好,最都用例都改为模拟数据。因为数据库数据的维护太TM的麻烦了!


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/6686056.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-26
下一篇 2023-03-26

发表评论

登录后才能评论

评论列表(0条)

保存