kmo*_*ote 6 unit-testing ssms sql-server-2008
有没有办法在SSMS中为SQL查询创建简单的单元测试?我是T-SQL和SSMS的新手,但如果可能的话,我想尝试将一些旧的TDD习惯带入这个领域.
因此,例如,当我编写DDL以创建复杂函数和什么不是时,我想有一些方法来包含一个单元测试(失败时)实际上会导致输出面板在执行时显示错误消息.(这与在正常编程环境中"破坏构建"类似.)
目前,当我编写一个语法正确的函数,然后按F5执行它,输出消息是:
Command(s) completed successfully.
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一些简单的SQL技巧来模拟基本的红灯/绿灯测试用例.所以我会编写一系列测试语句,只有当我的用户定义函数按预期运行时才会通过.否则将显示错误消息,例如:
Msg 207, Level 16, State 1, Line 2
Invalid statement.
Run Code Online (Sandbox Code Playgroud)
这将允许我立即跳到失败的测试,看看我做错了什么.
我不希望有任何"内置"的东西,但有什么方法可以"假装"吗?
更新:我刚刚了解到你可以在SS2012中抛出异常,我确信我可以将其用于此目的,但不幸的是我现在仍然坚持使用SS2008.在SS2008中有什么可比性的吗?
这些是我可以推荐的2个框架
TST
使用TST测试SQL Server代码
http://www.infoq.com/articles/tst-sql-server
tSQLt
SQL Test(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.
) ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4247 次 |
| 最近记录: |