2012-06-27 5 views
6

Есть ли способ создать простые модульные тесты для SQL-запросов в SSMS? Я довольно новичок в TMS-SQL & SSMS, но я хотел бы попытаться перенести некоторые из моих старых привычек TDD на эту арену, если это возможно.Единичные тесты в SQL Server Management Studio

Так, например, когда я пишу DDL для создания сложных функций, а что-нет, я хотел бы иметь некоторый способ включить модульный тест, который (при сбое) фактически заставит панель вывода отображать сообщение об ошибке после выполнения. (. Это будет аналогичным тому, чтобы «разорвать сборки» в нормальной среде программирования)

В настоящее время, когда я пишу функцию, которая синтаксически правильно, а затем нажмите клавишу F5, чтобы выполнить его, сообщение вывод:

Command(s) completed successfully. 

Что я ищу - это простой простейший трюк SQL для симуляции базовых тестов с красным светом/зеленым светом. Поэтому я бы написал серию тестовых утверждений, которые будут проходить только в том случае, если моя пользовательская функция работает по назначению. В противном случае сообщение об ошибке будет отображаться, например:

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

, который позволил бы мне сразу перейти к неисправному тесту и посмотреть, что я сделал неправильно.

Я не ожидаю, что для этого будет что-то «встроенное», но можно ли каким-то образом «подделать» его?

Update: Я только что узнал, вы можете throw exceptions в SS2012, который я уверен, что я мог бы использовать только для этой цели, но, к сожалению, я застрял с SS2008 на данный момент. Есть ли что-то сопоставимое в SS2008?

+0

Обновление: я просто наткнулся на эту полезную запись: [«Начало работы с тестовым дизайном в SQL Server»] (http://www.sqlmag.com/print/sql-server/test-driven-design-sql -server-142881) – kmote

ответ

6

Эти 2 рамки я могу рекомендовать

T.S.T.

http://tst.codeplex.com/

тестирование SQL-кода сервера с TST

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

tSQLt

http://tsqlt.org/

SQL Test (бегунок для tSQLt)

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

Update 1

Чтение ваш ответ может быть, вы найдете следующие отвала полезно.

TRY CATCH был представлен с SQL Server 2005 (и по этой причине никогда не следует смотреть на более старую, чем в 2005 году). Вы можете на самом деле (повторить) выбросить исключение, используя хранимую процедуру, указанную в моем дампе, включая номер строки. В SQL Server 2012 они (finaly!) Представили бросок, поскольку вы упоминаете, что Tsql является надежным языком через 14 лет.

Итак, вот моя свалка, мне нужно ее очистить в какой-то день, чтобы ее более дружественная копия.

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

Когда я впервые задал этот вопрос, я просто искал некоторые «одно вкладыши», которые могли бы выполнить мою заявленную задачу, а не полные рамки. Но эти предложения велики - мне придется их исследовать. Благодаря! – kmote

+0

Я разработчик C#, и я почти всегда делаю свою логику на этом языке, чтобы я мог тестировать единицы. Но при работе со 100 миллионами строк transact sql можно сделать разницу между часом обработки или 12. Хорошо, что эти рамки существуют, хотя я должен в свое время полагаться на свою собственную мини-инфраструктуру до сих пор. Я играл с вышеупомянутыми 2, хотя и они выполняют свою работу. – buckley

+0

Спасибо за обновление, которое привело меня к исходному описанию 'usp_RethrowError' в [BOL] (http://msdn.microsoft.com/en-us/library/ms179296 (v = sql.105) .aspx). Очень интересный материал! Я не совсем уверен, как я могу использовать его в моей текущей ситуации, но я вижу, что это может быть чрезвычайно полезно в будущем. – kmote

0

Ну, я нашел возможное решение мой собственный вопрос: RAISERROR. Это «работает» в какой-то степени (по крайней мере, в том, как я был invisioning), что позволяет мне строить базовые тесты, как:

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

Это причудливая, но делает дисплей сообщение об ошибке, которое я могу нажать на чтобы перейти к оскорбительной строке кода (что в моем случае является неудачным модульным тестом) - хотя и с некоторой фиктивной информацией в первой строке.

+0

Я обновил свой ответ, если вам нужно (забросить) sql> 2005, и вы хотите получить доступ к номеру строки, изначально вызвавшему исключение (здесь используется C# jargon) – buckley

Смежные вопросы