SSDT 项目和使用已知数据管理集成测试

SSDT projects and managing Integration tests with known data

我正在迁移到 SSDT,以便对带有附带数据库的大型项目的数据库结构进行模式控制。该项目内部已经有数百个处于各种脆弱状态的集成测试。其中许多使用我称之为 "known data" 的东西来执行集成测试。测试依靠这些数据才能成功 运行。

过去,我们已经完成了集成测试数据库的 1:1 副本,用于在功能分支中进行测试,但我并不喜欢这个过程,因为它会增加服务器的膨胀。

使用 SSDT,有没有办法将此 "known data" 合并到 SSDT 项目或可用于事后复制的流程中?我已经有 post-deploy 脚本将种子数据(类型等)加载到系统中,因此我可以将所有已知数据放在那里,但这可能是许多额外的 sql 文件需要管理所以我对此并不狂热。

由于已知数据的复杂性和数量,使用位于数据库之上的应用程序来插入它是不切实际的。

我正在考虑探索 bacpac 选项,但在这样做之前想看看人们过去是否有任何其他方法来管理功能分支与已知数据的集成测试。

如果我没理解错的话,您可以在数据库之间复制所有数据以执行集成测试。

如果正确,您可以:

  1. 在单独的架构中创建存储过程以填充您的 table。例如 dbo.MyTable 将由 seed.usp_MyTable 或;
  2. 播种
  3. 在单独的数据库中创建存储过程以填充 table,再次使用智能命名约定。

对于这两个选项,主存储过程可用于执行所有种子过程。

两者的好处是:

  • 所有存储过程都是源代码控制的,确保历史 测试数据被捕获。
  • 以编程方式识别种子数据覆盖率非常简单 因为每个 table 都会有一个名称匹配的存储过程。
  • 启动种子过程非常简单 部署,只需包含一个 post-部署脚本或 SQL 任务来执行主种子程序。
  • 种子数据程序可用作额外的回归测试 在列或数据类型更改时检查源漂移。

每种方法各有利弊:

  1. 所有种子程序都属于同一个数据库 table他们提到的。这将 SSDT 项目简化为没有 需要外部参考。
  2. 不同的种子数据可以用于不同的 环境。对数据 table 项目的外部引用是 需要,但可以为每个创建不同的种子项目 环境。

您可以采用以下几种方法:

  1. 使用backups/snapshots
  2. 在单独的 .sqlproj / dacpac 中集成测试/测试数据
  3. 设置数据作为测试的一部分

1.使用 backups/snapshots

您可以获得已知状态的数据库,然后使用备份或快照。我不太喜欢这个,因为你总是需要让你的基础保持最新,或者时不时地刷新它。

2。单独的 .sqlproj / dacpac

中的集成测试/测试数据

这是我通常为单元测试所做的(集成测试,对我来说,通常使用调用数据库的应用程序的语言)。

我的解决方案中会有一个单独的 .sqlproj,它有一个 "Same Database" 对主项目的引用。将集成测试和测试种子数据的 Post-Deploy.sql 放入其中。

如果您有多个文件,请使用“:r”导入来包含这些文件,使用“:r”导入来包含 post-部署主项目与发布发生时一样,引用的 dacpacs 没有执行其 pre/post-deploy 脚本。

如果在部署测试项目和 /p:IncludeCompositeObject=True 之前没有使用过这样的引用

3。将数据设置为测试的一部分

如果您已经拥有一个大型套件,这可能会更难,但我通常会建议,作为每个测试设置的一部分,您获得的数据处于您知道适合该测试的状态。

这样它就可以阻止 运行 以不同顺序进行的测试等的任何脆弱性

我还没有为此查看 bacpac,这可能也是一种有趣的处理方式。

批量插入

到目前为止,我发现获取用于测试的静态数据的最快方法是使用 post 脚本中预先填充的数据文件中的 "BULK INSERT"。主要问题是我需要提供 BULK INSERT 的确切文件路径。但是,您可以为此使用发布变量。此解决方案是获取数据的最快方法,并且比 INSERT/MERGE 语句执行得更好。

INSERT/MERGE

如果没有那么多数据,那么 post 脚本中的 INSERT/MERGE 就可以正常工作。已经实现了可以帮助生成这些语句的存储过程。你可以查看一下on github.

tSQLt

与实际问题关系不大,但强烈建议使用tSQLt framework进行测试。它不是集成,而是单元测试,但如果使用得当,您将不需要预填充数据,它可以在任何数据库上运行。