[SQL]使用tSQLt進行資料庫單元測試

  • 572
  • 0

系統開發過程中,可能會為了方便,或是因為效能的關係,將商業邏輯寫在DB層。但是當數量一多,邏輯變複雜,接手Legacy Code,或是當自己的程式變成Legacy Cody時,就會發現維護起來異常困難。處理這類問題,Unit Test是一種方式。透過Unit Test,一方面再提高可測試性時,同時提高可維護性。另一方面,也讓邏輯的修改更順暢,更容易提早抓到bug。tSQLt是一套Open Source的SQL DB Unit Test Framework,可以協助我們達成上述的目標。

安裝tSQLt

tSQLt其實是許多SQL資料庫物件的集合,可依照以下的方式進行安裝

1.下載tSQLt

請到tSQLt的官網下載安裝檔,他是一份zip檔

2.SQL Server須設定啟動CLR

執行以下的sql statement:

EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;

3.所使用的Database需要設定TRUSTWORTHY

開啟一個連線到要進行Unit Test的Database後,執行以下的sql statement:

DECLARE @cmd NVARCHAR(MAX);
SET @cmd='ALTER DATABASE ' + QUOTENAME(DB_NAME()) + ' SET TRUSTWORTHY ON;';
EXEC(@cmd);

4.執行安裝sql statement

開啟一個連線到要進行Unit Test的Database後,執行由官網下載下來的zip檔中的tSQLt.class.sql。成功之後,在SQL Management Studio中可以看到以下訊息

P00

執行完成後,可以在Database下看到會多了一些Table、Stored Procedure、Function以及tSQLt Schema。

P01

這樣tSQLt就算安裝完成。

一個簡單的Unit Test

資料庫的邏輯主要集中在Stored Procedure及Function,所以這兩個就是tSQLt主要的測試對象。先建立一個簡單的Function作為測試對象。

CREATE FUNCTION ConvertCurrency(
    @rate DECIMAL(10,4),
    @amount MONEY)
RETURNS MONEY
AS
BEGIN
    DECLARE @NewAmount MONEY;
    SELECT @NewAmount = @amount * @rate;
    RETURN @NewAmount;
END

這個Function做的事情是輸入匯率及金額,以計算換匯後的金額。

1.建立TestClass

第一步是建立TestClass,這其實是建立一個Schema,用來標注需要進行的測試案例。例如,建立一個名為LabHello的TestClass,則執行以下sql statement:

EXEC tSQLt.NewTestClass 'LabHello';
GO

2.建立測試案例

這是透過Stored Procedure來進行的,而該Stored Procedure的Schema就是上一步驟所建立的TestClass。而Stored Procedure的名字必須是test開頭(不分大小寫),才會被視為一個可被執行的測試案例。

CREATE PROCEDURE LabHello.[test that ConvertCurrency converts using given conversion rate]
AS
BEGIN
    DECLARE @actual MONEY;
    DECLARE @rate DECIMAL(10,4); SET @rate = 1.2;
    DECLARE @amount MONEY; SET @amount = 2.00;

    SELECT @actual = dbo.ConvertCurrency(@rate, @amount);

    DECLARE @expected MONEY; SET @expected = 2.4;   --(rate * amount)
    EXEC tSQLt.AssertEquals @expected, @actual;

END;
GO

可以看到tSQLt提供了一個SP-tSQLt.AssertEquals,用法就跟我們在寫C#程式的單元測試時會用到的3A Pattern一樣,去檢測實際值預測值是否相同。

3.進行測試

tSQLt提供了幾個不同的SP以進行測試,我們可以直接使用tSQLt.RunAll來執行所有的測試案例

EXEC tSQLt.RunAll

如果沒意外,應該可以在Message頁籤中看到執行的結果為:

P02

現在模擬商業邏輯修改錯誤,例如把匯率的算法由乘法改為加法。

ALTER FUNCTION ConvertCurrency(
    @rate DECIMAL(10,4),
    @amount MONEY)
RETURNS MONEY
AS
BEGIN
    DECLARE @NewAmount MONEY;
    SELECT @NewAmount = @amount + @rate;
    RETURN @NewAmount;
END

然後再執行一次EXEC tSQLt.RunAll,應該可以看到測試結果如下:

P03

可以看到會顯示測試結果為Failure,並顯示相關訊息。