sql-server-2008 - SQL Server Management Studio 中的单元测试

标签 sql-server-2008 unit-testing ssms

有没有办法在 SSMS 中为 SQL 查询创建简单的单元测试?我对 T-SQL 和 SSMS 还很陌生,但如果可能的话,我想尝试将我的一些旧 TDD 习惯带入这个领域。

因此,例如,当我编写 DDL 来创建复杂的函数等等时,我想有一些方法来包含一个单元测试(失败时)实际上会导致输出面板在执行时显示错误消息. (这类似于正常编程环境中的“破坏构建”。)

目前,当我编写一个语法正确的函数,然后按 F5 执行它时,输出消息是:

Command(s) completed successfully.

我正在寻找的是一些简单的 SQL 技巧来模拟基本的红灯/绿灯测试用例。所以我会编写一系列测试语句,只有当我的用户定义函数按预期运行时才会通过。否则会显示错误信息,例如:
Msg 207, Level 16, State 1, Line 2
Invalid statement.

这将允许我立即跳转到失败的测试并查看我做错了什么。

我不希望有任何“内置”的东西,但是有什么方法可以“伪造”吗?

更新:我刚知道你可以throw exceptions在 SS2012 中,我确信我可以仅用于此目的,但不幸的是,我现在坚持使用 SS2008。 SS2008 有什么可比的吗?

最佳答案

这些是我可以推荐的 2 个框架

T.S.T.

http://tst.codeplex.com/

使用 TST 测试 SQL Server 代码

http://www.infoq.com/articles/tst-sql-server

tSQLt

http://tsqlt.org/

SQL 测试(tSQLt 的运行程序)

http://www.red-gate.com/products/sql-development/sql-test/

更新 1

阅读您的答案,也许您会发现以下转储很有用。

TRY CATCH 是在 SQL Server 2005 中引入的(出于这个原因,永远不要看那些比 2005 更早的东西)。您实际上可以(重新)使用我的转储中提到的存储过程抛出异常,包括行号。在 SQL Server 2012 中,他们(终于!)引入了 throw,正如您提到的,在 14 年后使 Tsql 成为一种健壮的语言。

所以这是我的转储,我需要有一天清理它,以便它更适合复制粘贴。

SET XACT_ABORT ON
SET CONCAT_NULL_YIELDS_NULL OFF

DECLARE @message varchar ( max ) 
DECLARE @who varchar ( 255 ) 
set @who = OBJECT_NAME(@@PROCID) -- name of the currently executing sproc

BEGIN TRY

-- ======================================================================================
SET @message = 'HELLO'
EXEC Log @who, @message

         ....

-- ======================================================================================
SET @message = 'GOODBYE'
EXEC Log @who, @message

END TRY

BEGIN CATCH


        -- ======================================================================================
--If an error generated in a TRY block causes the state of the current transaction to be invalidated, the transaction is classified as an uncommittable transaction.
--An error that ordinarily ends a transaction outside a TRY block causes a transaction to enter an uncommittable state when the error occurs inside a TRY block.
-- http://msdn.microsoft.com/en-us/library/ms175976.aspx
       if XACT_STATE() = -1 rollback;

    -- ======================================================================================
SET @message = 'Rolling Back transaction if present'
EXEC Log @who, @message

     -- Its important to rollback the transaction at the very start of the catch.
-- Otherwise the records that are written to the log will also be roll backed.

IF @@TRANCOUNT > 0 
BEGIN
ROLLBACK TRAN 
END

-- ======================================================================================
SET @message = 'Error Occured '
set @message = @message + ' ERROR_NUMBER() : ' + cast(ERROR_NUMBER() as varchar(max))
set @message = @message + ' ERROR_SEVERITY() : ' + cast(ERROR_SEVERITY() as varchar(max))
set @message = @message + ' ERROR_STATE() : ' + cast(ERROR_STATE() as varchar(max))
set @message = @message + ' ERROR_PROCEDURE() : ' +cast(ERROR_PROCEDURE() as varchar(max))
set @message = @message + ' ERROR_LINE() : ' + cast(ERROR_LINE() as varchar(max))
set @message = @message + ' ERROR_MESSAGE() : ' + cast(ERROR_MESSAGE() as varchar(max))

EXEC Log @who, @message

  exec usp_RethrowError


END CATCH


Error logging sproc and table

CREATE PROCEDURE [dbo].[Log]
(
@who varchar(255),
@message varchar(max)
)
AS

SET XACT_ABORT ON
SET CONCAT_NULL_YIELDS_NULL OFF

INSERT INTO [ApplicationLog]
(
[Date],
[Level],
[Logger],
[Host],
[Message]
)
VALUES
(
getDate(),
'INFO',
@who,
'dummy',
@message
)

CREATE TABLE [dbo].[ApplicationLog] (
[Id]            [int] IDENTITY(1, 1) NOT NULL,
[Date]          [datetime] NOT NULL,
[Thread]        [varchar](255)  NULL,
[Level]         [varchar](50) NOT NULL,
[Logger]        [varchar](255)  NOT NULL,
[Host]          [varchar](50)  NOT NULL,
[Message]       [varchar](max)  NOT NULL,
[Exception]     [varchar](max) NULL
)


Rethrow an exception

ALTER PROCEDURE [dbo].[usp_RethrowError]
 -- BOL contains a good example of that, there is a stored procedure called usp_RethrowError

AS -- Return if there is no error information to retrieve.

SET XACT_ABORT ON
SET CONCAT_NULL_YIELDS_NULL OFF

IF ERROR_NUMBER() IS NULL 
  RETURN ;

DECLARE @ErrorMessage NVARCHAR(4000),
  @ErrorNumber INT,
  @ErrorSeverity INT,
  @ErrorState INT,
  @ErrorLine INT,
  @ErrorProcedure NVARCHAR(200) ;

    -- Assign variables to error-handling functions that 
    -- capture information for RAISERROR.
SELECT  @ErrorNumber = ERROR_NUMBER(), @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE(), @ErrorLine = ERROR_LINE(),
        @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-') ;

    -- Building the message string that will contain original
    -- error information.
SELECT  @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' +
        'Message: ' + ERROR_MESSAGE() ;

    -- Raise an error: msg_str parameter of RAISERROR will contain
    -- the original error information.
RAISERROR (@ErrorMessage, @ErrorSeverity, 1, @ErrorNumber, -- parameter: original error number.
  @ErrorSeverity, -- parameter: original error severity.
  @ErrorState, -- parameter: original error state.
  @ErrorProcedure, -- parameter: original error procedure name.
  @ErrorLine-- parameter: original error line number.
        ) ;

关于sql-server-2008 - SQL Server Management Studio 中的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11235460/

相关文章:

java - 模拟方法在 Mockito 中抛出 NullPointerException

javascript - 使用 Jest 测试一个应该抛出错误的函数,但总是收到 "function did not throw"错误

sql-server-2008 - 是否有在 SSRS 2008 R2 或 2012 中本地化 "parameters/prompt"的解决方案?

sql-server - 解释死锁并修复它

java - EasyMock "Unexpected method call"尽管有 expect 方法声明

sql - Exec <存储过程> 非常慢

c# - SSMS 中的网格控件

SQL Server 2008+ : Best method for detecting if two polygons overlap?

sql - 在后台运行大型查询 MS SQL

sql-server - 如何更改 ssms 2017 中的引用突出显示颜色?