Каков наилучший способ проверить хранимую процедуру? - PullRequest
24 голосов
/ 29 сентября 2008

Как и во многих компаниях, которым требуется полный доступ через хранимые процедуры, у нас, похоже, много бизнес-логики, запертой в sprocs. Эти вещи просто сложно проверить, а некоторые из них стали глупыми. У кого-нибудь есть набор лучших практик, которые могут немного облегчить уверенную проверку этих вещей?

В настоящее время мы поддерживаем около 30 «проблемных» баз данных, с которыми мы работаем. Это не всегда хорошо документировано и, конечно, не автоматизировано.

Ответы [ 8 ]

10 голосов
/ 29 сентября 2008

Коллега клянется инфраструктурой тестирования TSQLUnit . Может быть стоит посмотреть на ваши потребности.

4 голосов
/ 30 сентября 2008

У нас был очень тонкий слой доступа к данным, который в основном представлял собой хранимые процедуры, похожие на методы C #. Наш тестовый набор NUnit тогда имел SetUp / TearDown для создания / отката транзакции и тестирования методов, которые вызывались в DAL. Ничего сложного, и оказалось проще в обслуживании, чем набор тестов TSQLUnit.

2 голосов
/ 26 октября 2012

Попробуйте TST. Вы можете скачать и установить его с: http://tst.codeplex.com/

2 голосов
/ 08 мая 2009

Один из методов, который я использовал, - это написание «временного» модульного теста для рефакторинга конкретной хранимой процедуры. Вы сохраняете данные из набора запросов из базы данных и сохраняете их там, где их может получить модульный тест.

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

Альтернативой является параллельное выполнение двух хранимых процедур и сравнение наборов результатов.

Это особенно хорошо работает для хранимых процедур только для выбора, но обновления, вставки и удаления являются более сложными.

Я использовал этот метод, чтобы получить код в состоянии, когда он более восприимчив к модульному тестированию, либо проще, либо и тому, и другому.

2 голосов
/ 29 сентября 2008

Я заметил, что ваш пост был помечен как SqlServer. Если это так, то вам стоит взглянуть на Team Edition for Database Professionals, которая является частью Visual Studio. Вот несколько статей:

Последняя на самом деле является кросс-платформенной платформой, в то время как DBPro на данный момент является исключительно SQL Server.

2 голосов
/ 29 сентября 2008

Не уверен, что это то, что вы ищете, но так как вы используете SQL Server: я считаю, что LINQ - это отличный инструмент для тестирования хранимых процедур. Вы можете просто перетащить хранимые процедуры на диаграмму DBML, а затем вызвать их как методы в текстовом тексте данных. Превосходит настройку ADO-соединений и т. Д. Для тестового жгута. Например, если вы настроили тестовый проект в Visual Studio, вы можете просто протестировать свои процедуры, как методы на другом объекте. Если ваши хранимые процессы возвращают наборы результатов, я думаю, что LINQ преобразует это в анонимные переменные, к которым вы должны иметь доступ через IEnumerable или IQueryable (кто-то, пожалуйста, проверьте это). Но если вы возвращаете только коды возврата, это должен быть быстрый и довольно простой способ.

1 голос
/ 08 октября 2008

Вот мой не требующий высоких технологий способ быстрого хранения примеров, которые удобно расположены в DDL

<code>
USE [SpacelySprockets]
<br/>GO
<br/>/****** Object:  StoredProcedure [dbo].[uspBrownNoseMrSpacely]    Script Date: 02/03/3000 00:24:41 ******/
<br/>SET ANSI_NULLS ON
<br/>GO
<br/>SET QUOTED_IDENTIFIER ON
<br/>GO
<br/>--================================
<br/>--Stored Procedure DDL:
<br/>--================================

--Example Inputs
<br/>/*
<br/>DECLARE @SuckupPloyId              int
<br/>DECLARE @SuckupIdentityRecordId        int 
<br/>SET        @SuckupPloyId               = 3
<br/>*/

-- =============================================
<br/>-- Author:     6eorge Jetson
<br/>-- Create date: 01/02/3000
<br/>-- Description:    Sucks up to the boss
<br/>-- =============================================
<br/>CREATE PROCEDURE [dbo].[uspBrownNoseMrSpacely]
<br/>    @SuckupPloyId              int
<br/>   ,@SuckupIdentityRecordId    int OUTPUT 
<br/>AS
<br/>BEGIN
    DECLARE @EmployeeId     int
    DECLARE @SuckupPoints   int
    DECLARE @DateTimeStamp  datetime

    SET     @EmployeeId     = dbo.svfGetEmployeeId('6eorge Jetson')
    SET     @SuckupPoints   = dbo.svfGetSuckupPoints(@SuckupPloyId)
    SET     @DateTimeStamp  = getdate()

    --Data state-changing statement in sproc
    INSERT INTO [dbo].[tblSuckupPointsEarned]([EmployeeId], [SuckupPoints], [DateTimeStamp] )
    VALUES (@EmployeeId, @SuckupPoints, @DateTimeStamp)

    SET @SuckupIdentityRecordId = @@Identity
END
</code>
--Unit Test Evidence Display
/*
SELECT
     @EmployeeId    as EmployeeId
    ,@SuckupPoints  as SuckupPoints
    ,@DateTimeStamp as DateTimeStamp
*/


--==========================================================================
--After editing for low-tech, non-state changing "unit-like" test invocation
--==========================================================================

--Example Inputs
DECLARE @SuckupPloyId               int
DECLARE @SuckupIdentityRecordId     int 
SET     @SuckupPloyId               = 3

/*
-- =============================================
-- Author:      6eorge Jetson
-- Create date: 01/02/3000
-- Description: Sucks up to the boss
-- =============================================
CREATE PROCEDURE [dbo].[uspBrownNoseMrSpacely]
     @SuckupPloyId              int
    ,@SuckupIdentityRecordId    int OUTPUT 
AS
BEGIN
*/
    DECLARE @EmployeeId     int
    DECLARE @SuckupPoints   int
    DECLARE @DateTimeStamp  datetime

    SET     @EmployeeId     = dbo.svfGetEmployeeId('6eorge Jetson')
    SET     @SuckupPoints   = dbo.svfGetSuckupPoints(@SuckupPloyId)
    SET     @DateTimeStamp  = getdate()

    --Data state-changing statement now commented out to prevent data state change
--  INSERT INTO [dbo].[tblSuckupPointsEarned]([EmployeeId], [SuckupPoints], [DateTimeStamp] )
--    VALUES (@EmployeeId, @SuckupPoints, @DateTimeStamp)

    SET @SuckupIdentityRecordId = @@Identity

--END   --Need to comment out the sproc "END" also

--Unit Test Evidence Display
SELECT
     @EmployeeId    as EmployeeId
    ,@SuckupPoints  as SuckupPoints
    ,@DateTimeStamp as DateTimeStamp


Он работает еще лучше для udfs, так как нет необходимости менять состояние. Понятно, что я бы не рекомендовал это вместо инфраструктуры тестирования, но если я буду придерживаться этой простой дисциплины стоимости секунд

Утверждают, что мой sproc размером с управляемый размер проходит, по крайней мере, простой «модульный тест»

перед выполнением CREATE PROCEDURE я обнаружил, что совершаю меньше ошибок (скорее всего из-за дисциплины, а не самого теста).

1 голос
/ 29 сентября 2008

Это похоже на ужасную политику. Возможно, вы можете написать хранимую процедуру, которая выполняет SQL, и начать переносить код для выполнения там.

В любом случае я бы протестировал вызов хранимых процедур с помощью традиционной инфраструктуры автоматизации. Как шлюз между приложением и данными, они должны рассматриваться как интеграционные тесты, а не как единичные тесты. Тем не менее, вы можете использовать основанную на xUnit инфраструктуру модульного тестирования для управления ими. Если у ваших тестов есть доступ для запуска SQL для базы данных, возможно, с помощью метода, который я упоминал ранее, вы сможете утверждать, что были внесены правильные изменения.

Одна из проблем заключается в том, что вы указываете, что они становятся длинными. Я бы порекомендовал разбить их на подпрограммы и сделать их как можно меньше. Это облегчает тестирование и обслуживание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...