我正在尝试为我们的集成测试定义一种使用测试数据库(在 SQL Server 中)的方式。
我的想法是在集成测试程序集启动时执行这些步骤:
- 创建一个完全空的数据库
- 运行“创建数据库对象”脚本来创建所有相关的数据库对象(表、视图、序列等)
- 填写“基础数据”(查找值等)
(db)_Basis
为未来的集成测试拍摄称为“基线”的数据库快照
现在,在每个测试类(包含 1-n 个测试)之前,我计划简单地执行“从快照还原”以返回到数据库的定义明确、或多或少“空”的状态。到目前为止,它就像一个魅力。
但是,有一组集成测试需要在大型测试数据库上运行 - 所以我希望在每个测试夹具(具有 n 个单独测试的类)之前执行此操作
- 从
(db)_Basis
快照恢复数据库 - 将这 50'000+ 行数据插入数据库
- 创建另一个快照
(db)_With_Testdata
快照
然后对于每个测试,将数据库重置为定义良好的(db)_With_Testdata
快照版本,运行测试,验证结果等等。
问题是:我似乎不能同时拥有两个数据库快照 - 一旦我这样做,我就无法将我的数据库恢复到其中任何一个......我不断收到此错误:
消息 3137,级别 16,状态 4,第 9 行
数据库无法还原。主名称或快照名称指定不正确,未删除所有其他快照,或者缺少文件。消息 3013,级别 16,状态 1,第 9 行
RESTORE DATABASE 异常终止。
这真的是 SQL Server 数据库快照的工作原理吗?似乎非常限制.....如果我不能直接回到原始的“(db)_Basis”快照,我会理解 - 但仅仅因为我现在有两个快照,我什至不能回到最近的一个?!?!?
不幸的是,这是设计使然。
取自 BOL 页面“将数据库还原为数据库快照”:
作为替代方案,您可以删除第一个快照
(db)_Basis
。我可以理解这似乎非常有限,但这样看:快照是基于原始数据文件的稀疏文件,因此恢复到特定快照无论如何都会使所有快照无效(基本数据文件将被恢复操作更改) . 限制可能很烦人,但看起来并非不合理。另一种观点是进行备份并恢复它们 - 因为您只是创建带有一些查找值的空数据库和模式。
此外,只需插入 50K 行,数据库就不会那么大。如果您使用压缩,备份大小也会更小。
您可以有一个 TSQL 代理作业或只是脚本(也许您可以创建存储过程并根据您获得的输出在测试后调用它)。
(db)_Basis
(db)_With_Testdata
让您的集成脚本运行并根据最终输出,您可以运行上述任一作业以恢复到您想要的任何点。
我觉得备份/恢复方法在您的场景中非常优雅,因为您遇到了数据库快照限制。此外,Paul Randal 在博客中谈到了包括 SQL Server 2012 在内的所有版本中的一个讨厌的错误(不确定它是否在以后的 CU 中修复)