【发布时间】:2017-08-17 20:59:18
【问题描述】:
我最近开始通过 Redgate 的 SQL 测试使用 TSQLT 来创建和运行单元测试。我遇到了一个问题。执行时间超过几分钟的单元测试将超时,从而停止执行所有其他单元测试。
如何延长 tSQLt 的超时时间?
我的“单元测试”可能实际上不是单元测试,但我不熟悉另一种更适合的测试方法。
我正在开展一个项目,以提高我们数据仓库的夜间刷新速度。目前,这个过程需要五个小时。通过重新安排任务以尽可能并行运行,我将时间缩短到两个小时。我的问题是,除非我能找到一种方法来证明新流程与旧流程具有完全相同的最终结果,否则 QA 将在接下来的一年中检查每个表中每一行的每一列中的每个值。要么这样,要么该项目将因为“太难”而被废弃。
所以我想出的测试是这样的: 我有一个数据库,在使用我创建的新方法在我们的测试环境中处理结果表后,我运行一个脚本来复制结果表。然后,回到测试环境,我运行旧进程来更新表。然后,我对每个表运行一个单元测试,以证明使用新方法处理的归档表的内容与使用旧方法重新处理的表的内容完全相同。
很遗憾,由于其中一些表的大小(数百万行),一些单元测试会超时。以下是我收到的错误:
测试程序:[HR360_unitTest1].[HR360_DW_Job6].[test fact_group_clients 相同的内容] 在 emr\preprod System.Data.SqlClient.SqlException (0x80131904):超时已过期。这 在操作完成之前经过的超时时间或 服务器没有响应。 ---> System.ComponentModel.Win32Exception (0x80004005): 等待操作超时 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection,Action`1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler、SqlDataReader 数据流、 BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean & dataReady) 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior,字符串 resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、布尔 returnStream、布尔 异步,Int32 超时,任务和任务,布尔 asyncWrite,SqlDataReader ds,布尔值 describeParameterEncryptionRequest)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法,TaskCompletionSource
1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 完成,字符串方法名,布尔型 sendToPipe,Int32 超时, 布尔 asyncWrite) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 RedGate.SQLTest.tSQLt.FrameworkWrapper.#kz(SqlCommand #LGj) 在 RedGate.SQLTest.tSQLt.FrameworkWrapper.#7qHc(String #2xAd, SqlParameter[] #LvPb) 在 RedGate.SQLTest.tSQLt.FrameworkWrapper.#qd4b(String #LGxc) 在 RedGate.SQLTest.tSQLt.TestRunner.Execute(SqlConnection 连接) ClientConnectionId:519569ed-03ce-4510-b226-9ff18e0f1d8d 错误 编号:-2,状态:0,等级:11
如果无法增加 tSQLt 的超时时间,那么我将不得不寻找另一种方法来自动测试这些表的内容是否相同(以可随意重复的方式)或放弃该项目.
【问题讨论】:
-
您是否尝试过更改连接字符串中的超时属性? msdn.microsoft.com/en-us/library/…
-
不幸的是,对连接字符串的调用是由 tSQLt 框架进行的。我发布了这个问题,因为我无法找到一种方法来告诉 tSQLt 使用不同的超时参数进行这些调用。您是说有一种方法可以在 tSQLt 周围进行结束运行并设置将覆盖 tSQLt 在运行时使用的任何值的参数?
-
只是想一想,您是否尝试过从命令行运行 tSQLt(使用 sqlcmd 或 sql-ps)?或者,如果这只是一次性的,您甚至可以在 SSMS 中运行它并将结果窗口导出为“证据”。我认为我从未在 SSMS 中看到过 tSQLt 超时,并且我们经常在大约 18 分钟内运行超过 6000 次测试而没有问题。虽然,在 VSTS 中运行这些测试时,我们必须逐类运行以避免 CI 过程超时。超时可能在 SQL 测试中,而不是 tSQLt 框架本身。
-
谢谢@datacentricity!事实证明,你的怀疑是对的。经过进一步测试,我的问题似乎与 Redgate SQL 测试有关,而不是 tSQLt。我按照您的建议使用 tSQLt.Run 运行了一项测试。我应该小心我的愿望,因为它在 19 小时后仍在运行。为了验证它不只是卡住了,我创建了一个只执行 WAITFOR DELAY '00:10' 的假存储过程,并为此过程创建了一个单元测试。通过 SQL 测试运行的单元测试超时。使用 tSQLt.Run 的单元测试成功。
标签: sql-server unit-testing tsqlt