2012-06-27 30 views
6

SSMSでSQLクエリの単体テストを作成する方法はありますか?私はかなりT-SQL & SSMSに新しくなっていますが、私は可能なかぎり私の古いTDDの習慣のいくつかをこのアリーナに持って行きたいと思っています。SQL Server Management Studioのユニットテスト

たとえば、DDLを記述して複雑な関数を作成する場合や何もない場合は、(失敗した場合)出力パネルに実際に表示される単位テストを含める方法があります実行時にエラーメッセージ。 (これは、通常のプログラミング環境で「ビルドを壊す」にanalagousだろう)現在

、私は文法的に正しい関数を記述する場合、それを実行するF5キーを打つ、出力メッセージは次のとおりです。

Command(s) completed successfully. 

私が探しているのは、基本的な赤色光/緑色光のテストケースをシミュレートする簡単なSQLトリックです。だから私は私のユーザー定義関数が意図したとおりに動作している場合にのみ合格する一連のテスト文を書くだろう。私は失敗し、テストにすぐにジャンプして、私が間違っていたかを確認することができるようになる

Msg 207, Level 16, State 1, Line 2 
Invalid statement. 

:それ以外の場合、エラーメッセージは、次のような、表示されます。

私はそこに何か「組み込み」があるとは思っていませんが、私はそれを「偽造」できますか?

アップデート:私はちょうどあなたができる私はちょうどこの目的のために使用することができます確信しているが、残念ながら、私は今のSS2008とこだわっているSS2012でthrow exceptionsを、学びました。 SS2008に匹敵するものはありますか?

+0

更新:[SQL Serverでテスト駆動型設計を開始する](http://www.sqlmag.com/print/sql-server/test-driven-design-sql) -server-142881) – kmote

答えて

6

これらは私が

をお勧めすることができます2つのフレームワークですT.S.T. TST

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

tSQLt

http://tsqlt.org/

SQLテスト(tSQLt用ランナー)と

http://tst.codeplex.com/

のテストSQL Serverコード

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

アップデート1

多分あなたは便利以下ダンプを見つけるあなたの答えを読みます。

TRY CATCHはSQL Server 2005で導入されました(このため、2005年より古いことは決してありません)。私のダンプに記載されているストアドプロシージャ(行番号を含む)を使用して、実際に(再)例外をスローすることができます。 SQL Server 2012では、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. 
     ) ; 
+0

私が最初にこの質問をしたとき、私は、完全なフレームワークではなく、私の定められたタスクを達成するかもしれないいくつかの "1つのライナー"を探していました。しかし、これらの提案は素晴らしいです - 私はそれらを探索する必要があります。ありがとう! – kmote

+0

私はC#開発者です。私はその言語で私のロジックをほとんどいつでも行うので、単体テストができます。しかし、100万行のトランザクションを処理する場合、SQLは1時間の処理と12時間の差を生み出すことができます。私は今まで自分のミニフレームワークに頼っていたにもかかわらず、これらのフレームワークは存在します。私は上記の2と一緒に演奏し、彼らは仕事を完了する。 – buckley

+0

[BOL](http://msdn.microsoft.com/en-us/library/ms179296(v= sql.105).aspx)の 'usp_RethrowError'のオリジナルの説明に私を導きました。非常に面白いもの!私は現在の状況でどのように使用するのかがはっきりしていませんが、将来的には非常に役立つことがわかります。 – kmote

0

私自身の質問には、可能な解決策が見つかりました:RAISERROR。私のような基本的なテストを構築することができます(少なくとも私はinvisioningた方法で)ある程度この「作品」、:

IF dbo.myTestedFunction(@parm) != @myExpectedResult 
    RAISERROR('>> Unit Test FAILED! -- %d, 11, 0, @parm) 

それは風変わりだが、それは私が上のクリックできる表示エラーメッセージを表示しません(私の場合、失敗した単体テストである)違反行にジャンプする - 最初の行にいくつかの偽の情報があるにもかかわらず。

+0

sql> 2005を(再)スローする必要があり、もともと例外を引き起こしていた行番号にアクセスする必要がある場合は、私の回答を更新しました(ここではC#jargon) – buckley

関連する問題