逐步解說:使用自訂測試條件來驗證預存程序的結果
在這個延伸模組功能逐步解說中,您將建立測試條件,並透過建立 SQL Server 單元測試來驗證其功能。 此程序包含建立測試條件的類別庫專案,以及簽署及安裝專案。 如果您已經擁有想要更新的測試條件,請參閱如何:將 Visual Studio 2010 自訂測試條件從舊版升級至 SQL Server Data Tools。
本逐步解說將說明下列工作:
如何建立測試條件。
如何使用強式名稱簽署組件。
如何將必要參考加入至專案。
如何建立測試條件。
如何安裝新的測試條件。
如何測試新的測試條件。
您必須擁有含最新版 SQL Server Data Tools 的 Visual Studio 2010 或 Visual Studio 2012 才能完成此逐步解說。 如需詳細資訊,請參閱安裝 SQL Server Data Tools。
建立自訂測試條件
首先,您將建立類別庫。
在 [檔案] 功能表上,按一下 [新增],然後按一下 [專案]。
在 [新增專案] 對話方塊中,按一下 [專案類型] 之下的 [Visual C#]。
在 [範本] 底下,選取 [類別庫]。
在 [名稱] 文字方塊中,輸入 ColumnCountCondition 然後按一下 [確定]。
接下來,簽署專案。
按一下 [專案] 功能表上的 [ColumnCountCondition 屬性]。
在 [簽署] 索引標籤上,選取 [簽署組件] 核取方塊。
在 選擇強式名稱金鑰檔 方塊中,按一下 <新增...>。
[建立強式名稱金鑰] 對話方塊隨即出現。
在 [金鑰檔名稱] 方塊中,輸入 SampleKey。
輸入並確認密碼,然後按一下 [確定]。 當您建置方案時,金鑰檔是用來簽署組件。
按一下 [ 檔案 ] 功能表上的 [ 全部儲存]。
在 [建置] 功能表上,按一下 [建置方案]。
接下來,將必要參考加入至專案。
在 [方案總管] 中,選取 [ColumnCountCondition] 專案。
在 [專案] 功能表上,按一下 [加入參考] 顯示 [加入參考] 對話方塊。
選取 [.NET] 索引標籤。
在 [元件名稱] 欄中,找出並選取 [System.ComponentModel.Composition] 元件。 選取元件之後,按一下 [確定]。
加入必要的組件參考。 以滑鼠右鍵按一下專案節點,然後按一下 [加入參考]。 按兩下 [ 瀏覽 ] 並瀏覽至
C:\Program Files (x86)\Microsoft SQL Server\110\DAC\Bin
資料夾。 選擇 Microsoft.Data.Tools.Schema.Sql.dll,並按一下 [加入],然後按一下 [確定]。按一下 [專案] 功能表上的 [卸載專案]。
在 [方案總管] 中的該專案上按一下滑鼠右鍵,然後選擇 [編輯 <專案名稱>.csproj]。
匯入 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)' != ''" />
儲存並關閉檔案。 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選擇 [重新載入專案]。
在 [方案總管] 中專案的 [參考] 節點底下,會顯示必要的參考。
建立 ResultSetColumnCountCondition 類別
現在,將 Class1 命名為 ResultSetColumnCountCondition,並從 testcondition 來加以衍生。 ResultSetColumnCountCondition 類別是簡單的測試條件,可驗證 ResultSet 中所傳回資料行的數目。 您可以使用這個條件,確定預存程序的合約是否正確。
在 [方案總管] 中,以滑鼠右鍵按一下 [Class1.cs],按一下 [重新命名],然後輸入 ResultSetColumnCountCondition.cs。
按一下 [是],確認 Class1 的所有參考都要重新命名。
開啟 [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
從 testcondition 衍生該類別:
public class ResultSetColumnCountCondition : TestCondition
新增 ExportTestConditionAttribute。 請參閱如何:為 SQL Server 單元測試設計工具建立測試條件,以取得 UnitTesting.Conditions.ExportTestConditionAttribute 的詳細資訊。
[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; }
覆寫 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); }
使用 CategoryAttribute、DisplayNameAttribute和 DescriptionAttribute 屬性來新增以下測試條件屬性:
//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 工作階段並建立資料庫專案:
啟動第二個 Visual Studio 工作階段。
在 [檔案] 功能表上,按一下 [新增],然後按一下 [專案]。
在 [新增專案] 對話方塊中,於已安裝的範本清單中選取 [SQL Server] 節點。
在 [詳細資料] 窗格中,按一下 [SQL Server 資料庫專案]。
在 [名稱] 文字方塊中,輸入 SampleConditionDB,然後按一下 [確定]。
接下來必須建立單元測試。 在新的測試類別內建立 SQL Server 單元測試:
在 [測試] 功能表上,按一下 [新增測試] 以顯示 [加入新測試] 對話方塊。
您也可以開啟 [方案總管],以滑鼠右鍵按一下測試專案,指向 [加入],然後按一下 [新增測試]。
在範本清單中,按一下 [SQL Server 單元測試]。
在 [測試名稱] 中,輸入 SampleUnitTest。
在 [加入至測試專案] 中,按一下 [建立新的 Visual C# 測試專案]。 然後按一下 [確定] 以顯示 [新增測試專案] 對話方塊。
輸入 SampleUnitTest 作為專案名稱。
按一下 [取消] 即可建立單元測試,而不設定測試專案使用資料庫連線。 您的空白測試會出現在「SQL Server 單元測試設計工具」中。 Visual C# 原始程式碼檔會新增至測試專案中。
如需使用資料庫連線建立及設定資料庫單元測試的詳細資訊,請參閱如何:建立空白 SQL Server 單元測試。
按一下 [按一下此處以建立] 以完成建立單元測試。 您會看到新的測試條件顯示在 SQL Server 專案中。
注意
若要將自訂測試條件用於現有的單元測試專案,必須建立至少一個新的 SQL Server 單元測試類別。 建立測試類別期間,測試條件組件的必要參考就會加入至測試專案。
若要檢視新的測試條件:
在 [SQL Server 單元測試設計工具] 的 [測試條件] 底下,按一下 [名稱] 欄底下的 [inconclusiveCondition1] 測試。
按一下 [刪除測試條件] 工具列按鈕,以移除 inconclusiveCondition1 測試。
按一下 [測試條件] 下拉式清單,並選取 [ResultSet 資料行計數]。
按一下 [加入測試條件] 工具列按鈕,以加入自訂測試條件。
在 [屬性] 視窗中,設定 Count、Enabled 和 ResultSet 屬性。
如需詳細資訊,請參閱如何:將測試條件新增至 SQL Server 單元測試。