共用方式為


逐步解說:使用自訂測試條件來驗證預存程序的結果

 

在這個擴充功能逐步解說中,您將建立測試條件,並透過建立 SQL Server 單元測試來驗證其功能。此程序包含建立測試條件的類別庫專案,以及簽署及安裝專案。如果您已經有要更新的測試條件,請參閱 HOW TO:將 Visual Studio 2010 自訂測試條件從舊版升級至 SQL Server Data Tools

本逐步解說將說明下列工作:

  • 如何建立測試條件。

  • 如何使用強式名稱簽署組件。

  • 如何將必要參考加入至專案。

  • 如何建立測試條件。

  • 如何安裝新的測試條件。

  • 如何測試新的測試條件。

若要完成本逐步解說,必須有隨附最新版 Visual Studio 2010 的 Visual Studio 2012 或 SQL Server Data Tools。如需詳細資訊,請參閱安裝 SQL Server Data Tools

建立自訂測試條件

首先,您將建立類別庫。

  1. 在 [檔案] 功能表上,按一下 [新增],然後按一下 [專案]。

  2. 在 [新增專案] 對話方塊中,按一下 [專案類型] 底下的 [Visual C#]。

  3. 在 [範本] 底下,選取 [類別庫]。

  4. 在 [名稱] 文字方塊中,輸入 ColumnCountCondition,然後按一下 [確定]。

接下來,簽署專案。

  1. 按一下 [專案] 功能表上的 [ColumnCountCondition 屬性]。

  2. 在 [簽署] 索引標籤上,選取 [簽署組件] 核取方塊。

  3. 在 [選擇強式名稱金鑰檔] 方塊中,按一下 [<新增...>]。

    [建立強式名稱金鑰] 對話方塊隨即出現。

  4. 在 [金鑰檔名稱] 方塊中,輸入 SampleKey

  5. 輸入並確認密碼,然後按一下 [確定]。當您建置方案時,金鑰檔是用來簽署組件。

  6. 按一下 [檔案] 功能表上的 [全部儲存]。

  7. 按一下 [建置] 功能表上的 [建置方案]。

接下來,將必要參考加入至專案。

  1. 在 [方案總管] 中選取 ColumnCountCondition 專案。

  2. 在 [專案] 功能表上,按一下 [加入參考] 顯示 [加入參考] 對話方塊。

  3. 選取 [.NET] 索引標籤。

  4. 在 [元件名稱] 欄中,找出並選取 System.ComponentModel.Composition 元件。選取元件之後,按一下 [確定]。

  5. 新增必要的組件參考。以滑鼠右鍵按一下專案節點,然後按一下 [加入參考]。按一下 [瀏覽] 並巡覽至 C:\Program Files (x86)\MicrosoftSQL Server\110\DAC\Bin 資料夾。選擇 Microsoft.Data.Tools.Schema.Sql.dll,並按一下 [新增],然後按一下 [確定]。

  6. 按一下 [專案] 功能表上的 [卸載專案]。

  7. 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選擇 [編輯 .csproj]。

  8. 匯入 Microsoft.CSharp.targets 之後,加入下列 Import 陳述式:

    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\SSDT\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="'$(VisualStudioVersion)' == ''" />  
    
    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="'$(VisualStudioVersion)' != ''" />  
    
  9. 儲存並關閉檔案。在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選擇 [重新載入專案]。

    在 [方案總管] 中專案的 [參考] 節點底下,會顯示必要的參考。

建立 ResultSetColumnCountCondition 類別

現在,將 Class1 重新命名為 ResultSetColumnCountCondition,並從 TestCondition 衍生這個類別。ResultSetColumnCountCondition 類別是簡單的測試條件,會驗證結果集中傳回的資料行數目。您可以使用這個條件,確定預存程序的合約是否正確。

  1. 在 [方案總管] 中,以滑鼠右鍵按一下 Class1.cs,按一下 [重新命名],然後輸入 ResultSetColumnCountCondition.cs

  2. 按一下 [],確認 Class1 的所有參考都要重新命名。

  3. 開啟 ResultSetColumnCountCondition.cs 檔案,然後將下列 Using 陳述式加入至檔案:

    using System;  
    using System.ComponentModel;  
    using System.Data;  
    using System.Data.Common;  
    using Microsoft.Data.Tools.Schema.Sql.UnitTesting;  
    using Microsoft.Data.Tools.Schema.Sql.UnitTesting.Conditions;  
    
    namespace ColumnCountCondition {  
        public class ResultSetColumnCountCondition  
    
  4. TestCondition 衍生類別:

    public class ResultSetColumnCountCondition : TestCondition  
    
  5. 加入 ExportTestConditionAttribute。如需 HOW TO:建立 SQL Server 單元測試設計工具的測試條件 的詳細資訊,請參閱 ExportTestConditionAttribute

    [ExportTestCondition("ResultSet Column Count", typeof(ResultSetColumnCountCondition))]  
        public class ResultSetColumnCountCondition : TestCondition  
    
  6. 建立成員變數和建構函式:

            private int _resultSet;  
            private int _count;  
            private int _batch;  
    
            public ResultSetColumnCountCondition() {  
                _resultSet = 1;  
                _count = 0;  
                _batch = 1;  
            }  
    
  7. 覆寫 Assert 方法。此方法包含 IDbConnection (表示資料庫連接) 的引數,以及 SqlExecutionResult。方法使用 DataSchemaException 來處理錯誤:

           //method you need to override  
            //to perform the condition verification  
            public override void Assert(DbConnection validationConnection, SqlExecutionResult[] results)  
            {  
                //call base for parameter validation  
                base.Assert(validationConnection, results);  
    
                //verify batch exists  
                if (results.Length < _batch)  
                    throw new DataException(String.Format("Batch {0} does not exist", _batch));  
    
                SqlExecutionResult result = results[_batch - 1];  
    
                //verify resultset exists  
                if (result.DataSet.Tables.Count < ResultSet)  
                    throw new DataException(String.Format("ResultSet {0} does not exist", ResultSet));  
    
                DataTable table = result.DataSet.Tables[ResultSet - 1];  
    
                //actual condition verification  
                //verify resultset column count matches expected  
                if (table.Columns.Count != Count)  
                    throw new DataException(String.Format(  
                        "ResultSet {0}: {1} columns did not match the {2} columns expected",  
                        ResultSet, table.Columns.Count, Count));  
            }  
    
    Add the following method, which overrides the ToString method:  
    C#  
            //this method is called to provide the string shown in the  
            //test conditions panel grid describing what the condition tests  
            public override string ToString()  
            {  
                return String.Format(  
                    "Condition fails if ResultSet {0} does not contain {1} columns",  
                    ResultSet, Count);  
            }  
    
  8. 使用 CategoryAttributeDisplayNameAttributeDescriptionAttribute 屬性 (Attribute),加入下列測試條件屬性 (Property):

            //below are the test condition properties  
            //that are exposed to the user in the property browser  
            #region Properties  
    
            //property specifying the resultset for which  
            //you want to check the column count  
            [Category("Test Condition")]  
            [DisplayName("ResultSet")]  
            [Description("ResultSet Number")]  
            public int ResultSet  
            {  
                get { return _resultSet; }  
    
                set  
                {  
                    //basic validation  
                    if (value < 1)  
                        throw new ArgumentException("ResultSet cannot be less than 1");  
    
                    _resultSet = value;  
                }  
            }  
    
            //property specifying  
            //expected column count  
            [Category("Test Condition")]  
            [DisplayName("Count")]  
            [Description("Column Count")]  
            public int Count  
            {  
                get { return _count; }  
    
                set  
                {  
                    //basic validation  
                    if (value < 0)  
                        throw new ArgumentException("Count cannot be less than 0");  
    
                    _count = value;  
                }  
            }  
             #endregion  
    

最後的程式碼如下所列:

using System;  
using System.ComponentModel;  
using System.Data;  
using System.Data.Common;  
using Microsoft.Data.Tools.Schema.Sql.UnitTesting;  
using Microsoft.Data.Tools.Schema.Sql.UnitTesting.Conditions;  
  
namespace ColumnCountCondition  
{  
  
    [ExportTestCondition("ResultSet Column Count", typeof(ResultSetColumnCountCondition))]  
    public class ResultSetColumnCountCondition : TestCondition  
    {  
        private int _resultSet;  
        private int _count;  
        private int _batch;  
  
        public ResultSetColumnCountCondition()  
        {  
            _resultSet = 1;  
            _count = 0;  
            _batch = 1;  
        }  
  
        //method you need to override  
        //to perform the condition verification  
        public override void Assert(DbConnection validationConnection, SqlExecutionResult[] results)  
        {  
            //call base for parameter validation  
            base.Assert(validationConnection, results);  
  
            //verify batch exists  
            if (results.Length < _batch)  
                throw new DataException(String.Format("Batch {0} does not exist", _batch));  
  
            SqlExecutionResult result = results[_batch - 1];  
  
            //verify resultset exists  
            if (result.DataSet.Tables.Count < ResultSet)  
                throw new DataException(String.Format("ResultSet {0} does not exist", ResultSet));  
  
            DataTable table = result.DataSet.Tables[ResultSet - 1];  
  
            //actual condition verification  
            //verify resultset column count matches expected  
            if (table.Columns.Count != Count)  
                throw new DataException(String.Format(  
                    "ResultSet {0}: {1} columns did not match the {2} columns expected",  
                    ResultSet, table.Columns.Count, Count));  
        }  
  
        //this method is called to provide the string shown in the  
        //test conditions panel grid describing what the condition tests  
        public override string ToString()  
        {  
            return String.Format(  
                "Condition fails if ResultSet {0} does not contain {1} columns",  
                ResultSet, Count);  
        }  
  
        //below are the test condition properties  
        //that are exposed to the user in the property browser  
        #region Properties  
  
        //property specifying the resultset for which  
        //you want to check the column count  
        [Category("Test Condition")]  
        [DisplayName("ResultSet")]  
        [Description("ResultSet Number")]  
        public int ResultSet  
        {  
            get { return _resultSet; }  
  
            set  
            {  
                //basic validation  
                if (value < 1)  
                    throw new ArgumentException("ResultSet cannot be less than 1");  
  
                _resultSet = value;  
            }  
        }  
  
        //property specifying  
        //expected column count  
        [Category("Test Condition")]  
        [DisplayName("Count")]  
        [Description("Column Count")]  
        public int Count  
        {  
            get { return _count; }  
  
            set  
            {  
                //basic validation  
                if (value < 0)  
                    throw new ArgumentException("Count cannot be less than 0");  
  
                _count = value;  
            }  
        }  
  
        #endregion  
    }  
}  
  

接下來,建置專案。

編譯專案及安裝測試條件

按一下 [建置] 功能表上的 [建置方案]。

接下來,將組件資訊複製到 Extensions 目錄。當 Visual Studio 啟動時,它會識別 %Program Files%\Microsoft Visual Studio \Common7\IDE\Extensions\Microsoft\SQLDB\TestConditions 目錄和子目錄中的任何擴充功能,並讓這些擴充功能可供使用:

從輸出目錄中,將 ColumnCountCondition.dll 組件檔複製到 %Program Files%\Microsoft Visual Studio \Common7\IDE\Extensions\Microsoft\SQLDB\TestConditions 目錄。

根據預設,編譯過的 .dll 檔案的路徑是 YourSolutionPath\YourProjectPath\bin\Debug 或 YourSolutionPath\YourProjectPath\bin\Release。

接下來,啟動新的 Visual Studio 工作階段並建立資料庫專案。若要啟動新的 Visual Studio 工作階段並建立資料庫專案:

  1. 啟動第二個 Visual Studio 工作階段。

  2. 在 [檔案] 功能表上,按一下 [新增],然後按一下 [專案]。

  3. 在 [新增專案] 對話方塊中,選取已安裝的範本清單中的 [SQL Server] 節點。

  4. 在詳細資料窗格中,按一下 [SQL Server 資料庫專案]。

  5. 在 [名稱] 文字方塊中,輸入 SampleConditionDB,然後按一下 [確定]。

接下來必須建立單元測試。若要在新的測試類別內建立 SQL Server 單元測試:

  1. 在 [測試] 功能表上,按一下 [新增測試] 顯示 [加入新測試] 對話方塊。

    您也可以開啟 [方案總管],以滑鼠右鍵按一下測試專案,指向 [加入],然後按一下 [新增測試]。

  2. 在範本清單中,按一下 [SQL Server 單元測試]。

  3. 在 [測試名稱] 中,輸入 SampleUnitTest

  4. 在 [加入至測試專案],按一下 [建立新的 Visual C# 測試專案]。然後按一下 [確定] 顯示 [新增測試專案] 對話方塊。

  5. 輸入專案名稱 SampleUnitTest

  6. 按一下 [取消] 即可建立單元測試,而不設定測試專案使用資料庫連接。您的空白測試便會出現在 SQL Server 單元測試設計工具中。Visual C# 原始程式碼檔會加入至測試專案。

    如需建立及設定使用資料庫連接之資料庫單元測試的詳細資訊,請參閱 HOW TO:建立空白 SQL Server 單元測試

  7. 按一下 [按一下此處以建立] 完成建立單元測試。您會看到新的測試條件顯示在 SQL Server 專案中。

提示


若要將自訂測試條件用於現有的單元測試專案,必須建立至少一個新的 SQL Server 單元測試類別。建立測試類別期間,測試條件組件的必要參考就會加入至測試專案。

若要檢視新的測試條件:

  1. 在 [SQL Server 單元測試設計工具] 的 [測試條件] 中,按一下 [名稱] 欄底下的 inconclusiveCondition1 測試。

  2. 按一下 [刪除測試條件] 工具列按鈕,移除 inconclusiveCondition1 測試。

  3. 按一下 [測試條件] 下拉式清單,並選取 [結果集資料行計數]。

  4. 按一下 [加入測試條件] 工具列按鈕,加入自訂測試條件。

  5. 在 [屬性] 視窗中,設定 Count、Enabled 和 ResultSet 屬性。

    如需詳細資訊,請參閱HOW TO:將測試條件加入至 SQL Server 單元測試

請參閱

SQL Server 單元測試的自訂測試條件