Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MSTest单元测试(VS 2012)与SQL Server,间歇性主键冲突_Sql Server_Sql Server 2008_Visual Studio 2012_Mstest - Fatal编程技术网

Sql server MSTest单元测试(VS 2012)与SQL Server,间歇性主键冲突

Sql server MSTest单元测试(VS 2012)与SQL Server,间歇性主键冲突,sql-server,sql-server-2008,visual-studio-2012,mstest,Sql Server,Sql Server 2008,Visual Studio 2012,Mstest,我正在处理一个非常奇怪的问题。起初,我认为这是清理测试数据的问题。。。但是在完全重构我的测试数据清理代码并且仍然看到完全相同的行为之后。。。我不知所措 我在不同的课程中有245个单元测试方法。每个类都有自己独特的测试数据,我初始化这些对象,然后在每个测试方法中,数据通常被插入数据库,然后通过测试进行操作。每个测试类都有一个ClassCleanup方法,该方法从数据库中清除所有测试数据,并且ClassCleanup也在TestInitialize上运行,以确保在运行任何其他测试方法之前清除所有内容

我正在处理一个非常奇怪的问题。起初,我认为这是清理测试数据的问题。。。但是在完全重构我的测试数据清理代码并且仍然看到完全相同的行为之后。。。我不知所措

我在不同的课程中有245个单元测试方法。每个类都有自己独特的测试数据,我初始化这些对象,然后在每个测试方法中,数据通常被插入数据库,然后通过测试进行操作。每个测试类都有一个ClassCleanup方法,该方法从数据库中清除所有测试数据,并且ClassCleanup也在TestInitialize上运行,以确保在运行任何其他测试方法之前清除所有内容

当我使用VS 2012测试资源管理器“全部运行”时,有22个测试失败。它们都会因主键约束冲突的一些变化而失败。这意味着,当他们为这些测试初始化数据时,数据没有从该类中以前的测试方法中清除。如果我重新运行所有测试,每次都会有相同的测试失败。这是相当可复制的。不管我运行了多少次所有测试。这27个测试失败,主键冲突

然而,奇怪的是,如果我只重新运行那些失败的测试,只有9个测试失败。这也是可复制的,也就是说,无论我只运行这27个之前失败的测试多少次,14个都会失败,其余的都会通过。这会继续下去,因为我只运行失败的测试,直到我达到一个测试都没有失败的点。还应该注意的是,如果我单独运行每个测试类,那么一切都会通过

我知道这是什么样子

“很明显,您没有清理测试数据。”如果是这样的话,那么无论发生什么情况,每次运行时我都会看到相同的测试失败。这27个测试应该在每次运行时失败,而不仅仅是在我运行其他所有测试时

“类之间不能有唯一的主键,并且没有清理的对象。”请参见上文。即使我的类中重复了主键(我没有,因为我个人在不同的类中对测试数据上的主键的唯一性进行了三次检查),因为这些测试不会在单独的线程上同时运行(通过记录ThreadId进行了验证),不管怎样,任何给定测试的清理代码都会清除重复的数据

“你不能使用连接池。”不,事实上我是。我已经使用SQL事件探查器验证了请求确实是池化的。此外,由于这些测试不是并行运行的,因此只有一个连接线程

“你不应该使用连接池。”嗯,是的,我应该这样做,因为底层代码库支持各种web项目,但是为了论证,我尝试在禁用连接池的情况下运行所有测试(在连接字符串中使用pooling=false),得到了完全相同的结果。行为上没有任何改变

“您的本地环境一定出了问题。”我在其他同事的开发设备上运行这些测试(附带使用SQL 2012)时也得到了相同的结果。这不是我的环境所独有的,甚至不是我的SQL Server版本所独有的

“您应该尝试从命令行运行mstest。”已经这样做了。同样的结果


如果有人遇到过类似的情况,请告诉我。我知道我肯定遗漏了一些简单的东西,因为这类问题通常都是这样,但我已经尽可能多地介绍了解决这些问题的基本方法。

不确定为什么你的失败是这样的,但我有一些类似的东西,现在我在设置中添加了一个
transactionscope

public void SetUp()
{
 _transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
}
并在拆卸时处理。这解决了我的数据库问题,避免了我必须编写手动清理代码。

以下内容基于以下假设,即您的数据库处于完全恢复模式,并且您在测试期间不执行任何恢复或其他欺骗操作(例如分离/重新连接数据库等)

这里有一个相当繁琐的方法来调查您的问题,但是可以保证提供解决这个问题所需的数据

  • 在启动测试套件之前对数据库进行完整备份。我们将要恢复数据库,因此还要确保您有足够的磁盘空间来存储2-3个数据库文件副本

  • 为事件创建Sql探查器跟踪选择RPC启动/完成、Sql批处理启动/完成、Sql语句启动/完成、SP语句启动/完成、TM:*完成、SQLTransaction、DTCTransaction和用户错误消息。捕获所有列

  • 重现问题运行最少数量的测试以产生故障。让测试完成,以便捕获所有清理代码,然后停止探查器跟踪

  • 进行事务日志备份我们可能需要此备份用于以后的时间点恢复

  • 在跟踪中找到故障如果您遇到主键故障,那么应该很容易找到,只需查找用户错误消息即可。写下错误发生的确切时间

  • 检查跟踪是否存在明显问题从错误开始,然后向后工作,直到找到失败的测试开始。记下上次失败测试的安装程序启动的确切时间。检查此范围内的所有sql。sql是否正是您所期望的?行数正确吗?transactionId正确吗?(对于不在事务中的每个语句,transactionId列应该不同,对于事务中的每个语句,transactionId列应该相同)。如果您的BEGIN TRAN/COMMIT TRAN/ROLLBACK TRAN不匹配,transactionId会让您知道

  • 将数据库恢复到故障前的右侧