연습: 사용자 지정 테스트 조건을 사용하여 저장 프로시저 결과 확인
업데이트: 2010년 12월
이 기능 확장 연습에서는 테스트 조건을 만든 다음 데이터베이스 단위 테스트를 만들어 해당 기능을 확인합니다. 이 프로세스에는 테스트 조건에 대한 클래스 라이브러리 프로젝트를 만들고 서명 및 등록하는 작업이 포함됩니다. 업데이트할 테스트 조건이 이미 있는 경우 방법: 이전 릴리스에서 사용자 지정 테스트 조건 업그레이드를 참조하십시오.
이 연습에서는 다음 작업을 수행합니다.
테스트 조건을 만듭니다.
강력한 이름으로 어셈블리에 서명합니다.
필요한 참조를 프로젝트에 추가합니다.
기능 확장을 빌드합니다.
새 기능 확장을 등록합니다.
새 기능 확장을 테스트합니다.
사전 요구 사항
이 연습을 완료하려면 Visual Studio Premium 또는 Visual Studio Ultimate이 설치되어 있어야 합니다.
사용자 지정 테스트 조건 만들기
먼저 클래스 라이브러리를 만듭니다.
클래스 라이브러리를 만들려면
파일 메뉴에서 새로 만들기를 클릭한 다음 프로젝트를 클릭합니다.
새 프로젝트 대화 상자의 프로젝트 형식에서 **Visual C#**을 클릭합니다.
템플릿에서 클래스 라이브러리를 선택합니다.
이름 텍스트 상자에 ColumnCountCondition을 입력한 다음 확인을 클릭합니다.
다음으로, 프로젝트에 서명합니다.
프로젝트에 서명하려면
프로젝트 메뉴에서 ColumnCountCondition 속성을 클릭합니다.
서명 탭에서 어셈블리 서명 확인란을 선택합니다.
강력한 이름 키 파일 선택 상자에서 **<새로 만들기...>**를 클릭합니다.
강력한 이름 키 만들기 대화 상자가 나타납니다.
키 파일 이름 상자에 SampleKey를 입력합니다.
암호를 입력하고 확인한 다음 확인을 클릭합니다.
솔루션을 빌드할 때 이 키 파일이 어셈블리에 서명하는 데 사용됩니다.
파일 메뉴에서 모두 저장을 클릭합니다.
빌드 메뉴에서 솔루션 빌드를 클릭합니다.
다음으로, 프로젝트에 필요한 참조를 추가합니다.
프로젝트에 적용 가능한 참조를 추가하려면
솔루션 탐색기에서 ColumnCountCondition 프로젝트를 선택합니다.
프로젝트 메뉴에서 참조 추가를 클릭합니다.
참조 추가 대화 상자가 열립니다.
.NET 탭을 선택합니다.
구성 요소 이름 열에서 다음 구성 요소를 찾습니다.
팁
구성 요소를 여러 개 선택하려면 Ctrl 키를 누른 상태에서 클릭합니다.
필요한 모든 구성 요소를 선택했으면 확인을 클릭합니다.
솔루션 탐색기에서 프로젝트의 참조 노드 아래에 선택한 참조가 표시됩니다.
ResultSetColumnCountCondition 클래스 만들기
다음으로, Class1의 이름을 ResultSetColumnCountCondition으로 바꾸고 TestCondition에서 파생시킵니다. ResultSetColumnCountCondition 클래스는 결과 집합에 반환된 열 수가 올바른지를 확인하는 간단한 테스트 조건입니다. 이 조건을 사용하여 저장 프로시저에 대한 계약이 올바른지를 확인할 수 있습니다.
테스트 조건 클래스를 만들려면
솔루션 탐색기에서 Class1.cs를 마우스 오른쪽 단추로 클릭하고 이름 바꾸기를 클릭한 다음 ResultSetColumnCountCondition.cs를 입력합니다.
예를 클릭하여 모든 참조의 이름을 Class1로 바꾸도록 확인합니다.
ResultSetColumnCountCondition.cs 파일을 열고 다음과 같은 using 문을 파일에 추가합니다.
using System; using System.Collections.Generic; using Microsoft.Data.Schema.UnitTesting; using Microsoft.Data.Schema.UnitTesting.Conditions; using Microsoft.Data.Schema.Extensibility; using System.ComponentModel; using System.Data; using System.Data.Common; using Microsoft.Data.Schema; namespace ColumnCountCondition { public class ResultSetColumnCountCondition
TestCondition에서 클래스를 파생시킵니다.
public class ResultSetColumnCountCondition : TestCondition
DatabaseSchemaProviderCompatibilityAttribute 특성을 추가합니다. 자세한 내용은 사용자 지정 데이터 생성기를 통해 특수 테스트 데이터 생성을 참조하십시오.
[DatabaseSchemaProviderCompatibility(typeof(DatabaseSchemaProvider))] [DatabaseSchemaProviderCompatibility(null)] [DisplayName("ResultSet Column Count")] public class ResultSetColumnCountCondition : TestCondition
이 테스트 조건에는 두 가지 호환성 특성이 모두 있으므로 다음 작업이 수행됩니다.
DatabaseSchemaProvider에서 상속하는 데이터베이스 스키마 공급자가 있을 때 조건이 로드됩니다. 이 조건은 데이터베이스 단위 테스트 디자이너에 데이터베이스 스키마 공급자 컨텍스트가 있는 경우를 처리합니다. 테스트 조건을 SQL Server에 대해 적용하려는 경우에는 대신 SqlDatabaseSchemaProvider를 지정할 수 있습니다.
데이터베이스 스키마 공급자가 없을 때 테스트 조건이 로드됩니다. 데이터베이스 단위 테스트 시 데이터베이스 스키마 공급자가 없는 확장이 로드되면 이 작업이 수행됩니다.
DisplayName 특성을 추가합니다.
[DatabaseSchemaProviderCompatibility(typeof(DatabaseSchemaProvider))] [DatabaseSchemaProviderCompatibility(null)] [DisplayName("ResultSet Column Count")] public class ResultSetColumnCountCondition : TestCondition
멤버 변수를 만듭니다.
{ private int _resultSet; private int _count; private int _batch;
생성자를 만듭니다.
public ResultSetColumnCountCondition() { _resultSet = 1; _count = 0; _batch = 1; }
Assert 메서드를 재정의합니다. 이 메서드에는 데이터베이스 연결을 나타내는 IDbConnection 및 ExecutionResult의 인수가 포함됩니다. 이 메서드는 오류 처리에 DataSchemaException을 사용합니다.
//method you need to override //to perform the condition verification public override void Assert(DbConnection validationConnection, ExecutionResult[] results) { //call base for parameter validation base.Assert(validationConnection, results); //verify batch exists if (results.Length < _batch) throw new DataSchemaException(String.Format("Batch {0} does not exist", _batch)); ExecutionResult result = results[_batch - 1]; //verify resultset exists if (result.DataSet.Tables.Count < ResultSet) throw new DataSchemaException(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 DataSchemaException(String.Format( "ResultSet {0}: {1} columns did not match the {2} columns expected", ResultSet, table.Columns.Count, Count)); }
ToString 메서드를 재정의하는 다음 메서드를 추가합니다.
//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.Collections.Generic;
using Microsoft.Data.Schema.UnitTesting;
using Microsoft.Data.Schema.UnitTesting.Conditions;
using Microsoft.Data.Schema.Extensibility;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using Microsoft.Data.Schema;
namespace ColumnCountCondition
{
DatabaseSchemaProviderCompatibility(typeof(DatabaseSchemaProvider))]
[DatabaseSchemaProviderCompatibility(null)]
[DisplayName("ResultSet Column Count")]
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, ExecutionResult[] 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));
ExecutionResult 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
}
}
다음으로, 프로젝트를 빌드합니다.
프로젝트를 빌드하려면
- 빌드 메뉴에서 솔루션 빌드를 클릭합니다.
다음으로, 프로젝트에서 생성된 버전, 문화권, PublicKeyToken 등의 어셈블리 정보를 수집합니다.
어셈블리 정보를 수집하려면
보기 메뉴에서 다른 창, 명령 창을 차례로 클릭하여 명령 창을 엽니다.
명령 창에서 다음 코드를 입력합니다. FilePath 대신 컴파일된 .dll 파일의 경로 및 파일 이름을 입력합니다. 이때 경로 및 파일 이름을 따옴표로 묶습니다.
참고
기본적으로 컴파일된 .dll 파일의 경로는 YourSolutionPath\bin\Debug 또는 YourSolutionPath\bin\Release입니다.
? System.Reflection.Assembly.LoadFrom(@"FilePath").FullName
Enter 키를 누릅니다. 이 줄은 특정 PublicKeyToken이 포함된 다음과 유사합니다.
"ColumnCountCondition, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nnnnnnnnnnnnnnnn"
이 어셈블리 정보를 적어 두거나 복사합니다. 이 정보는 다음 절차에서 사용됩니다.
다음으로, 이전 절차에서 수집한 어셈블리 정보를 사용하여 XML 파일을 만듭니다.
XML 파일을 만들려면
솔루션 탐색기에서 ColumnCountCondition 프로젝트를 선택합니다.
프로젝트 메뉴에서 새 항목 추가를 선택합니다.
템플릿 창에서 XML 파일 항목을 찾아 선택합니다.
이름 텍스트 상자에 ColumnCountCondition.Extensions.xml을 입력한 다음 추가 단추를 클릭합니다.
솔루션 탐색기의 프로젝트에 ColumnCountCondition.Extensions.xml 파일이 추가됩니다.
ColumnCountCondition.Extensions.xml 파일을 열고 다음 XML과 일치하도록 업데이트합니다. 이전 절차에서 검색한 버전, 문화권 및 PublicKeyToken을 바꿉니다.
<?xml version="1.0" encoding="utf-8"?> <extensions assembly="" version="1" xmlns="urn:Microsoft.Data.Schema.Extensions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:Microsoft.Data.Schema.Extensions Microsoft.Data.Schema.Extensions.xsd"> <extension type="ColumnCountCondition.ResultSetColumnCountCondition" assembly="ColumnCountCondition, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nnnnnnnnnnnnnnnn" enabled="true"/> </extensions>
파일 메뉴에서 저장을 클릭합니다.
다음으로, 어셈블리 정보와 XML 파일을 Extensions 디렉터리에 복사합니다. Visual Studio는 시작 시 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions 디렉터리 및 하위 디렉터리에 있는 모든 확장을 확인하여 세션에서 사용할 수 있도록 등록합니다.
어셈블리 정보와 XML 파일을 Extensions 디렉터리에 복사하려면
%Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\ 디렉터리에 CustomConditions라는 새 폴더를 만듭니다.
출력 디렉터리(기본적으로 My Documents\Visual Studio 2010\Projects\CustomConditions\CustomConditions\bin\Debug\)의 ColumnCountCondition.dll 어셈블리 파일을 사용자가 만든 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\CustomConditions 디렉터리에 복사합니다.
ColumnCountCondition.Extensions.xml 파일(기본적으로 My Documents\Visual Studio 2010\Projects\CustomConditions\CustomConditions\ 디렉터리에 있음)을 사용자가 만든 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\ CustomConditions 디렉터리에 복사합니다.
팁
%Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions 디렉터리의 폴더에 확장 어셈블리를 저장하는 것이 좋습니다. 이렇게 하면 제품에 포함된 확장과 사용자 지정 확장을 식별하는 데 도움이 됩니다. 확장을 특정 범주로 구성하는 데 폴더를 사용하는 것도 좋습니다.
다음으로, 새 Visual Studio 세션을 시작하고 데이터베이스 프로젝트를 만듭니다.
새 Visual Studio 세션을 시작하고 데이터베이스 프로젝트를 만들려면
두 번째 Visual Studio 세션을 시작합니다.
파일 메뉴에서 새로 만들기를 클릭한 다음 프로젝트를 클릭합니다.
새 프로젝트 대화 상자의 설치된 템플릿 목록에서 데이터베이스 노드를 확장하고 SQL Server를 클릭합니다.
세부 정보 창에서 SQL Server 2008 데이터베이스 프로젝트를 클릭합니다.
이름 텍스트 상자에 SampleConditionDB를 입력한 다음 확인을 클릭합니다.
다음으로, 단위 테스트를 만듭니다.
새 테스트 클래스 내부에 데이터베이스 단위 테스트를 만들려면
테스트 메뉴에서 새 테스트를 클릭합니다.
참고
솔루션 탐색기를 열고 테스트 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 추가를 가리키고 새 테스트를 클릭할 수도 있습니다.
새 테스트 추가 대화 상자가 나타납니다.
템플릿 목록에서 데이터베이스 단위 테스트를 클릭합니다.
테스트 이름에 SampleUnitTest를 입력합니다.
테스트 프로젝트에 추가에서 새 Visual C# 테스트 프로젝트 만들기를 클릭합니다.
확인을 클릭합니다.
새 테스트 프로젝트 대화 상자가 나타납니다.
프로젝트 이름에 SampleUnitTest를 입력합니다.
취소를 클릭하여 데이터베이스 연결을 사용하도록 테스트 프로젝트를 구성하지 않고 단위 테스트를 만듭니다.
참고
데이터베이스 연결 없이 데이터베이스 단위 테스트를 만들고 구성하는 방법에 대한 자세한 내용은 방법: 빈 데이터베이스 단위 테스트 만들기를 참조하십시오.
데이터베이스 단위 테스트 디자이너에 빈 테스트가 나타납니다. Visual C# 소스 코드 파일이 테스트 프로젝트에 추가됩니다.
**만들려면 여기를 클릭합니다.**를 클릭하여 단위 테스트 만들기를 마칩니다.
마지막으로, 새 조건이 SQL Server 프로젝트에 표시되는 것을 확인합니다.
새 조건을 보려면
데이터베이스 단위 테스트 디자이너의 테스트 조건, 이름 열에서 inconclusiveCondition1 테스트를 클릭합니다.
테스트 조건 삭제 도구 모음 단추를 클릭하여 inconclusiveCondition1 테스트를 제거합니다.
테스트 조건 드롭다운을 클릭하고 ResultSet 열 개수를 선택합니다.
테스트 조건 추가 도구 모음 단추를 클릭하여 사용자 지정 테스트 조건을 추가합니다.
속성 창에서 Count, Enabled 및 ResultSet 속성을 구성합니다.
자세한 내용은 방법: 데이터베이스 단위 테스트에 테스트 조건 추가를 참조하십시오.
참고 항목
작업
방법: 데이터베이스 단위 테스트 디자이너용 테스트 조건 만들기
개념
기타 리소스
변경 기록
날짜 |
변경 내용 |
이유 |
---|---|---|
2010년 12월 |
최종 코드를 약간 수정하여(특성) 고객 의견을 반영했습니다. |
고객 의견 |