2014年11月6日木曜日

SQL Server Unitテストフレームワーク tSQLt 【サンプルテスト】

前回説明した環境構築・テストデータの作成を行ったtSQLtの環境を使ったUnitTestのサンプル集です。最後にテストの実行方法とテストケースの削除等の後片付けについて記載しています。


-- テストケース1(期待値との単純比較)
-- テストケースはストアドプロシージャで書く
-- プロシージャの名前は日本語の名称でもエラーにならないが、テスト実行されなくなってしまう。
CREATE PROCEDURE [testGroup1].[TestCase1]
AS
BEGIN
 --テスト実行1回目
 DECLARE @n int
 EXEC dbo.TargetProcedure @n OUTPUT
 --1回目の結果比較
    EXEC tSQLt.AssertEquals 30, @n
 --テスト実行2回目
 EXEC dbo.TargetProcedure @n OUTPUT -- 1回目の結果を反映した2回目のテスト
 --2回目の結果比較
    EXEC tSQLt.AssertEquals 40, @n
END;
GO



-- テストケース2(FakeTableの使用例)
CREATE PROCEDURE [testGroup1].[TestCase2]
AS
BEGIN
 --実在するテーブルを偽テーブル(FakeTable)に置き換える。
 EXEC tSQLt.FakeTable 'dbo.TestTable';
 INSERT INTO dbo.TestTable(Id) VALUES(9) --外部キーの制約、NOT NULL制約を無視してデータの挿入が可能
 --テスト実行
 DECLARE @n int
 EXEC dbo.TargetProcedure @n OUTPUT
 --結果比較
    EXEC tSQLt.AssertEquals 9, @n
END;
GO



-- テストケース3(テーブル型の比較例)
CREATE PROCEDURE [testGroup1].[TestCase3]
AS
BEGIN
 --テスト実行
 CREATE TABLE #Actual (Name varchar(20),  Id int)
 INSERT INTO #Actual EXEC dbo.TargetProcedure2
 --期待値作成
 SELECT  TOP(0) * INTO #Expected FROM #Actual
 INSERT INTO #Expected VALUES ('abc',30)
 --結果比較
 EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual';
END;
GO



-- テストケース4(ストアドプロシージャ内のストアドプロシージャへの引数確認)
CREATE PROCEDURE [testGroup1].[TestCase4]
AS
BEGIN
 --ログを取得するストアドプロシージャを指定
    EXEC tSQLt.SpyProcedure 'dbo.TargetProcedure';
 --テスト実行
 EXEC dbo.TargetProcedure2
 SELECT *
  INTO #Actual
  FROM dbo.TargetProcedure_SpyProcedureLog;

--結果比較
 SELECT  TOP(0) * INTO #Expected FROM #Actual
 INSERT INTO #Expected VALUES (Null,'TargetProcedure2内で実行') --OUTPUTパラメータの値はNullになる。
 EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual';
END;
GO


-- テストケース5(ストアドプロシージャ内のストアドプロシージャのOUTPUTパラメータの書き換え)
CREATE PROCEDURE [testGroup1].[TestCase5]
AS
BEGIN
 --OUTPUTパラメータを書き換えるストアドプロシージャを指定
    EXEC tSQLt.SpyProcedure 'dbo.TargetProcedure','SET @maxId = 1000';

 --テスト実行
 CREATE TABLE #Actual (Name varchar(20),  Id int)
 INSERT INTO #Actual EXEC dbo.TargetProcedure2

 --結果比較
 SELECT  TOP(0) * INTO #Expected FROM #Actual
 INSERT INTO #Expected VALUES ('abc',1000)
 EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual';
END;
GO



-- テストケース6(ストアドプロシージャ内のストアドプロシージャを書き換える。)
CREATE PROCEDURE [testGroup1].[TestCase6]
AS
BEGIN

--OUTPUTパラメータを書き換えるストアドプロシージャを指定
    EXEC tSQLt.SpyProcedure 'dbo.TargetProcedure','SET @maxId = 1000';
    EXEC tSQLt.RemoveObject 'dbo.TargetProcedure';
    EXEC ('CREATE PROCEDURE TargetProcedure  @maxId INT OUTPUT, @dummy varchar(100) = NULL AS BEGIN SELECT @maxId = 2000 END;');

 --テスト実行
 CREATE TABLE #Actual (Name varchar(20),  Id int)
 INSERT INTO #Actual EXEC dbo.TargetProcedure2

--結果比較
 SELECT  TOP(0) * INTO #Expected FROM #Actual
 INSERT INTO #Expected VALUES ('abc',2000)
 EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual';
END;
GO




--テスト実行
tSQLt.Run [testGroup1]
go
-- テスト時に追加したデータは残らない。偽テーブルのデータも残らない。
select * from TestTable
select * from NumTable
go

--すべてのTestClassのテストを実行
tSQLt.RunAll


--削除
EXEC tSQLt.DropClass [testGroup1]
Drop Procedure TargetProcedure
Drop Procedure TargetProcedure2
Drop Procedure [testGroup1].[TestCase1]
Drop Procedure [testGroup1].[TestCase2]
Drop Procedure [testGroup1].[TestCase3]
Drop Procedure [testGroup1].[TestCase4]
Drop Procedure [testGroup1].[TestCase5]
Drop Procedure [testGroup1].[TestCase6]
Drop table TestTable
Drop table NumTable

--FakeTableを単体で実行すると元データを退避したテーブルが作られる。
--このテーブルに外部キーがある場合、参照されているテーブルが削除できなくなってしまうので
--以下のクエリで参照しているテーブルを探して探して消す。
--select OBJECT_NAME(parent_object_id),* from sys.foreign_keys
--FakeTableの名前変換情報は以下のテーブルに持っているようだが、ここまでは削除しない方が良さそう。
--select * from tSQLt.Private_RenamedObjectLog

0 件のコメント:

コメントを投稿