TSQL单元测试工具2017:SQL Server数据工具2017与tSQLt

时间:2017-12-17 22:21:05

标签: sql-server visual-studio sql-server-data-tools tsqlt sql-server-unit-testing

我有一个需要SQL Server单元测试的新项目,以及带有VSTS的CI / CD。

以下是所需的功能

  • 针对存储过程的SQL服务器单元测试,每个测试的初始目标表设置和清理

  • sql中的单元测试

  • 使用VSTS和Git的CI / CD

  • 易于设置且易于使用

我查看了SSDT 2017,看起来不错。但它似乎缺少一个功能,可以在预测试步骤中的每个测试之间轻松共享通用设置脚本。它可能缺少应该可用于日常使用的其他功能。但我可能错了。

哪种工具更适合2017年的常规SQL Server单元测试?

SQL Server Data Tools for Visual Studio

TSQLT

3 个答案:

答案 0 :(得分:17)

One of the reasons why there aren't more unit testing solutions out there for SQL development is because proper unit testing is inherently harder with databases so people don't do it. This is because databases maintain state and also referential integrity. Imagine writing a unit test for a stored procedure (Excel.Range testRng = (Excel.Range)sheet.Cells[1, 1]; testRng = testRng.get_Resize(data.GetLength(0), data.GetLength(1)); testRng.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, myObjectArrayofObjectArrays); ) that updates a status flag on an order_detail_update_status table. The order_detail table has a dependency on the order_detail and order_header tables, order_header in turn has foreign keys to product and customer whilst the product table may depend on employee, product_category and product_type. That is at least seven tables (probably more) that need to be populated with valid data just to write one test and all but one of those tables have nothing to do with the code under test.

So what you should be looking for in a unit testing solution is exactly that - the ability to test discrete units of code - with the minimum of set-up. So ideally, you would be able to just set up the required test data in supplier and ignore the rest of the tables - I am aware of only one testing framework that allows you to do that.

Additionally, unit tests should have minimal reasons to fail, in the above example, order_detail just updates a single row on the order_detail table. If a new not null column is added to the customer table, which is not handled by the test set-up then you have a scenario where our test could fail for a totally unrelated reason. This makes for very brittle tests and, under the pressure of tight delivery deadlines, developers will quickly give up writing and maintaining tests.

A suite of unit tests should be runnable in any order, with no interdependencies and a good test framework should support this along with set-up, tear down and support for mocking objects (which may or may not be part of the same framework). In the above scenario, the ability to mock the order_detail_update_status table to test a module that only touches the order_detail table is one of the most important features if you don't want to spend huge amounts of time fixing tests that are failing for no "good" reason.

So in terms of your requirements, and the above points, there is only one framework that I am aware of that does all of this - tSQLt. This is based on real-world experience - we had over 6,000 tSQLt unit tests on my last project. It includes the following feautures:

  • Unit test stored procedures, functions and views
  • Mock tables, views and functions
  • Mock (or spy) stored procedures - either for isolation, replay or pre-defined outcomes
  • Suite set-up
  • Automatic tear-down (as every test runs in it's own translation)
  • Unit tests are completely isolated and can be executed in any order

It works very well with VSTS in a CI/CD and, as all the unit tests are written in T-SQL, it is very easy to use.

The best way to use tSQLt in Visual Studio is to make use of composite projects - where application database objects and modules are maintained in one project whilst the tSQLt framework and all unit tests are part of a second project. There is a good aticle to get you started on this here.

I wrote a more detailed article on the benefits of tSQLt for Simple-Talk a few year back which might also be helpful

答案 1 :(得分:3)

你可以重复使用脚本,你可以做很多事情。快速回答您的问题就是使用 tSQLt 。到目前为止,没有其他单元测试框架可以使SQL Server如此强大/灵活且易于使用 tSQLt 。刚开始使用就是这样。在 SSDT 中设置非常简单快捷。 @datacentricity 为您写了足够的关于该框架的内容,如果您想了解更多内容,请阅读他提供的文章。

如果你要去 tSQLt 方向,我会添加一些东西让你的生活更轻松:

  • 对所有跨数据库链接对象使用同义词;
  • 使用 SSMS 中的标准脚本创建所有 tSQLt 对象,然后将对象导入 SSDT
  • tSQLt 对象创建单独的项目,并将其标记为与您愿意测试的数据库“相同的数据库
  • tSQLt 项目中创建预脚本,并从那里运行原始数据库项目的预脚本
  • tSQLt 项目中创建后脚本并从那里运行原始数据库项目的后脚本
  • tSQLt post-script 中作为最后一个语句写入“ EXEC tSQLt.RunAll
  • tSQLt 项目中创建发布脚本,并在设置中确保它将部署“扩展属性
  • 确保所有测试类(模式)都具有扩展属性语句

可能还有一些其他的细微差别,但只是从一些事情开始,我很确定你很快就会开始爱上 tSQLt

答案 2 :(得分:0)

请注意,微软正在推广slacker,请参见例如Channel 9: SQL Server Database Unit Testing in your DevOps pipeline。我们发现它在Azure SQL安装程序中可以正常工作。对于Azure SQL上的tSQLt,我记得有关启用CLR和TRUSTWORTHY选项的一些问题,但也看到它应该仍然有效,例如在这里: