SQL 服务器单元测试存储过程 - 生成测试数据
SQL Server Unit Testing Stored Procedures - generating testdata
我正在 2008R2 上的 VS2012 中为一个包含大量存储过程、表和外键的数据库编写存储过程单元测试。
对于每个存储过程测试,我在执行测试之前在相关表中生成几行数据。
我已经认识到这种做法会使测试对数据库更改非常敏感,尤其是对非空列或额外键的添加。
此类更改的级联影响可能导致必须保持大量测试同步。有些测试甚至可能与特定更改无关,但共享一个或多个相关表,因此准备失败。
此外,这样做的一个相当不便的后果是,很难区分在测试条件下失败的测试和在准备期间因密钥违规而失败的测试。
从大范围考虑,工作时间的后果可能很严重。
到目前为止我发现的关于这个主题的任何内容都过于笼统。
现在问题来了:对于开发数据库中的测试数据与在测试中生成测试数据的问题,是否存在相关的最佳实践?
我一直在尝试在 VS2012 中编写单元测试,发现它非常有限且繁琐。被你的问题触发,我刚刚阅读了一些我听说过的 tSQLt,它似乎是一个更强大的测试框架。例如。它模拟表、存储过程等。这允许减少依赖性,从而最大限度地减少数据库更改的级联影响。
即使你仍然想在 VS2012 中编写单元测试,你也可以使用模拟功能。只需确保 运行 在交易中进行测试即可。
来自他们网站的示例测试:
CREATE PROCEDURE SalesAppTests.[test SalesReport returns revenue and commission]
AS
BEGIN
-------Assemble
EXEC tSQLt.FakeFunction 'SalesApp.ComputeCommission', 'SalesAppTests.Fake_ComputeCommission';
EXEC tSQLt.FakeTable 'SalesApp.Employee';
EXEC tSQLT.FakeTable 'SalesApp.Sales';
INSERT INTO SalesApp.Employee (EmployeeId) VALUES (1);
INSERT INTO SalesApp.Sales (EmployeeId, SaleAmount) VALUES (1, 10.1);
INSERT INTO SalesApp.Sales (EmployeeId, SaleAmount) VALUES (1, 20.2);
-------Act
SELECT EmployeeId, RevenueFromSales, Commission
INTO SalesAppTests.Actual
FROM SalesApp.SalesReport;
-------Assert
SELECT TOP(0) *
INTO SalesAppTests.Expected
FROM SalesAppTests.Actual;
INSERT INTO SalesAppTests.Expected (EmployeeId, RevenueFromSales, Commission)
VALUES (1, 30.3, 1234.5678);
EXEC tSQLt.AssertEqualsTable 'SalesAppTests.Expected', 'SalesAppTests.Actual';
END;
GO
我正在 2008R2 上的 VS2012 中为一个包含大量存储过程、表和外键的数据库编写存储过程单元测试。
对于每个存储过程测试,我在执行测试之前在相关表中生成几行数据。
我已经认识到这种做法会使测试对数据库更改非常敏感,尤其是对非空列或额外键的添加。
此类更改的级联影响可能导致必须保持大量测试同步。有些测试甚至可能与特定更改无关,但共享一个或多个相关表,因此准备失败。
此外,这样做的一个相当不便的后果是,很难区分在测试条件下失败的测试和在准备期间因密钥违规而失败的测试。
从大范围考虑,工作时间的后果可能很严重。
到目前为止我发现的关于这个主题的任何内容都过于笼统。
现在问题来了:对于开发数据库中的测试数据与在测试中生成测试数据的问题,是否存在相关的最佳实践?
我一直在尝试在 VS2012 中编写单元测试,发现它非常有限且繁琐。被你的问题触发,我刚刚阅读了一些我听说过的 tSQLt,它似乎是一个更强大的测试框架。例如。它模拟表、存储过程等。这允许减少依赖性,从而最大限度地减少数据库更改的级联影响。
即使你仍然想在 VS2012 中编写单元测试,你也可以使用模拟功能。只需确保 运行 在交易中进行测试即可。
来自他们网站的示例测试:
CREATE PROCEDURE SalesAppTests.[test SalesReport returns revenue and commission]
AS
BEGIN
-------Assemble
EXEC tSQLt.FakeFunction 'SalesApp.ComputeCommission', 'SalesAppTests.Fake_ComputeCommission';
EXEC tSQLt.FakeTable 'SalesApp.Employee';
EXEC tSQLT.FakeTable 'SalesApp.Sales';
INSERT INTO SalesApp.Employee (EmployeeId) VALUES (1);
INSERT INTO SalesApp.Sales (EmployeeId, SaleAmount) VALUES (1, 10.1);
INSERT INTO SalesApp.Sales (EmployeeId, SaleAmount) VALUES (1, 20.2);
-------Act
SELECT EmployeeId, RevenueFromSales, Commission
INTO SalesAppTests.Actual
FROM SalesApp.SalesReport;
-------Assert
SELECT TOP(0) *
INTO SalesAppTests.Expected
FROM SalesAppTests.Actual;
INSERT INTO SalesAppTests.Expected (EmployeeId, RevenueFromSales, Commission)
VALUES (1, 30.3, 1234.5678);
EXEC tSQLt.AssertEqualsTable 'SalesAppTests.Expected', 'SalesAppTests.Actual';
END;
GO