연습: 데이터베이스 단위 테스트 생성 및 실행

이 연습에서는 여러 저장 프로시저의 동작을 확인하는 데이터베이스 단위 테스트를 만들어 봅니다. 올바르지 않은 응용 프로그램 동작을 초래할 수 있는 코드 오류를 쉽게 파악하려면 데이터베이스 단위 테스트를 만듭니다. 자동화된 테스트 도구 모음의 일부로 데이터베이스 단위 테스트와 응용 프로그램 테스트를 실행할 수 있습니다.

이 연습에서는 다음 작업을 수행합니다.

  • 데이터베이스 스키마가 포함된 스크립트 만들기

  • 데이터베이스 프로젝트 만들기 및 스키마 가져오기

  • 격리된 개발 환경에 데이터베이스 프로젝트 배포

  • 데이터베이스 단위 테스트 만들기

  • 테스트 논리 정의

  • 데이터베이스 단위 테스트 실행

  • 부정적 단위 테스트 추가

단위 테스트 중 하나에서 저장 프로시저의 오류를 찾은 후에는 해당 오류를 해결하고 테스트를 다시 실행합니다.

사전 요구 사항

이 연습을 완료하려면 데이터베이스를 만들고 배포할 권한이 있는 데이터베이스 서버에 연결할 수 있어야 합니다. 자세한 내용은 Visual Studio의 데이터베이스 기능에 필요한 권한을 참조하십시오.

데이터베이스 스키마가 포함된 스크립트 만들기

스키마를 가져올 수 있는 원본 스크립트를 만들려면

  1. 파일 메뉴에서 새로 만들기를 가리키고 파일을 클릭합니다.

    새 파일 대화 상자가 나타납니다.

  2. 범주 목록에서 일반이 아직 강조 표시되지 않은 경우 클릭합니다.

  3. 템플릿 목록에서 SQL 파일을 클릭한 다음 열기를 클릭합니다.

    Transact-SQL 편집기가 열립니다.

  4. 다음 Transact-SQL 코드를 복사하여 Transact-SQL 편집기에 붙여넣습니다.

    PRINT N'Creating Sales...';
    GO
    CREATE SCHEMA [Sales]
        AUTHORIZATION [dbo];
    GO
    PRINT N'Creating Sales.Customer...';
    GO
    CREATE TABLE [Sales].[Customer] (
        [CustomerID]   INT           IDENTITY (1, 1) NOT NULL,
        [CustomerName] NVARCHAR (40) NOT NULL,
        [YTDOrders]    INT           NOT NULL,
        [YTDSales]     INT           NOT NULL
    );
    GO
    PRINT N'Creating Sales.Orders...';
    GO
    CREATE TABLE [Sales].[Orders] (
        [CustomerID] INT      NOT NULL,
        [OrderID]    INT      IDENTITY (1, 1) NOT NULL,
        [OrderDate]  DATETIME NOT NULL,
        [FilledDate] DATETIME NULL,
        [Status]     CHAR (1) NOT NULL,
        [Amount]     INT      NOT NULL
    );
    GO
    PRINT N'Creating Sales.Def_Customer_YTDOrders...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [Def_Customer_YTDOrders] DEFAULT 0 FOR [YTDOrders];
    GO
    PRINT N'Creating Sales.Def_Customer_YTDSales...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [Def_Customer_YTDSales] DEFAULT 0 FOR [YTDSales];
    GO
    PRINT N'Creating Sales.Def_Orders_OrderDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [Def_Orders_OrderDate] DEFAULT GetDate() FOR [OrderDate];
    GO
    PRINT N'Creating Sales.Def_Orders_Status...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [Def_Orders_Status] DEFAULT 'O' FOR [Status];
    GO
    PRINT N'Creating Sales.PK_Customer_CustID...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [PK_Customer_CustID] PRIMARY KEY CLUSTERED ([CustomerID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
    GO
    PRINT N'Creating Sales.PK_Orders_OrderID...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [PK_Orders_OrderID] PRIMARY KEY CLUSTERED ([OrderID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
    GO
    PRINT N'Creating Sales.FK_Orders_Customer_CustID...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [FK_Orders_Customer_CustID] FOREIGN KEY ([CustomerID]) REFERENCES [Sales].[Customer] ([CustomerID]) ON DELETE NO ACTION ON UPDATE NO ACTION;
    GO
    PRINT N'Creating Sales.CK_Orders_FilledDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [CK_Orders_FilledDate] CHECK ((FilledDate >= OrderDate) AND (FilledDate < '01/01/2020'));
    GO
    PRINT N'Creating Sales.CK_Orders_OrderDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [CK_Orders_OrderDate] CHECK ((OrderDate > '01/01/2005') and (OrderDate < '01/01/2020'));
    GO
    PRINT N'Creating Sales.uspCancelOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspCancelOrder]
    @OrderID INT
    AS
    BEGIN
    DECLARE @Delta INT, @CustomerID INT
    BEGIN TRANSACTION
        SELECT @Delta = [Amount], @CustomerID = [CustomerID]
         FROM [Sales].[Orders] WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Orders]
       SET [Status] = 'X'
    WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Customer]
       SET
       YTDOrders = YTDOrders - @Delta
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    END
    GO
    PRINT N'Creating Sales.uspFillOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspFillOrder]
    @OrderID INT, @FilledDate DATETIME
    AS
    BEGIN
    DECLARE @Delta INT, @CustomerID INT
    BEGIN TRANSACTION
        SELECT @Delta = [Amount], @CustomerID = [CustomerID]
         FROM [Sales].[Orders] WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Orders]
       SET [Status] = 'F',
           [FilledDate] = @FilledDate
    WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Customer]
       SET
       YTDSales = YTDSales - @Delta
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    END
    GO
    PRINT N'Creating Sales.uspNewCustomer...';
    GO
    CREATE PROCEDURE [Sales].[uspNewCustomer]
    @CustomerName NVARCHAR (40)
    AS
    BEGIN
    INSERT INTO [Sales].[Customer] (CustomerName) VALUES (@CustomerName);
    SELECT SCOPE_IDENTITY()
    END
    GO
    PRINT N'Creating Sales.uspPlaceNewOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspPlaceNewOrder]
    @CustomerID INT, @Amount INT, @OrderDate DATETIME, @Status CHAR (1)='O'
    AS
    BEGIN
    DECLARE @RC INT
    BEGIN TRANSACTION
    INSERT INTO [Sales].[Orders] (CustomerID, OrderDate, FilledDate, Status, Amount) 
         VALUES (@CustomerID, @OrderDate, NULL, @Status, @Amount)
    SELECT @RC = SCOPE_IDENTITY();
    UPDATE [Sales].[Customer]
       SET
       YTDOrders = YTDOrders + @Amount
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    RETURN @RC
    END
    GO
    CREATE PROCEDURE [Sales].[uspShowOrderDetails]
    @CustomerID INT=0
    AS
    BEGIN
    SELECT [C].[CustomerName], CONVERT(date, [O].[OrderDate]), CONVERT(date, [O].[FilledDate]), [O].[Status], [O].[Amount]
      FROM [Sales].[Customer] AS C
      INNER JOIN [Sales].[Orders] AS O
         ON [O].[CustomerID] = [C].[CustomerID]
      WHERE [C].[CustomerID] = @CustomerID
    END
    GO
    
  5. 파일 메뉴에서 다른 이름으로 SqlQuery_1.sql 저장을 클릭합니다.

    다른 이름으로 파일 저장 대화 상자가 나타납니다.

  6. 개체 이름에 SampleImportScript.sql을 입력합니다.

    컴퓨터의 아무 위치에나 파일을 저장할 수 있습니다. 다음 절차에서 이 스크립트를 사용해야 하므로 저장 위치를 기록해 둡니다.

  7. 저장을 클릭합니다.

  8. 파일 메뉴에서 솔루션 닫기를 클릭합니다.

    다음에는 데이터베이스 프로젝트를 만들고 앞에서 만든 스크립트에서 스키마를 가져옵니다.

데이터베이스 프로젝트 만들기 및 스키마 가져오기

데이터베이스 프로젝트를 만들려면

  1. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.

    새 프로젝트 대화 상자가 나타납니다.

  2. 설치된 템플릿에서 데이터베이스 노드를 확장하고 SQL Server를 클릭합니다.

    참고

    Visual Studio Professional을 사용하는 경우에는 설치된 템플릿에서 데이터베이스 노드, SQL Server 노드를 차례로 확장한 다음 고급을 클릭합니다.

  3. 템플릿 목록에서 SQL Server 2008 데이터베이스 프로젝트를 클릭합니다.

    참고

    데이터베이스를 다른 데이터베이스 버전에 배포하려면 대상 서버에 해당하는 템플릿을 대신 선택합니다.

  4. 이름에 SimpleUnitTestDB를 입력합니다.

  5. 솔루션용 디렉터리 만들기 확인란이 아직 선택되어 있지 않은 경우 선택합니다.

  6. 소스 제어에 추가 확인란이 아직 선택 취소되어 있지 않은 경우 선택 취소하고 확인을 클릭합니다.

    데이터베이스 프로젝트가 만들어지고 솔루션 탐색기에 나타납니다. 다음에는 스크립트에서 데이터베이스 스키마를 가져옵니다.

스크립트에서 데이터베이스 스키마를 가져오려면

  1. 프로젝트 메뉴에서 스크립트 가져오기를 클릭합니다.

  2. 시작 페이지를 읽은 후 다음을 클릭합니다.

  3. 찾아보기를 클릭하고 SampleImportScript.sql 파일을 저장한 경로를 지정합니다.

  4. SampleImportScript.sql 파일을 두 번 클릭하고 마침을 클릭합니다.

    스크립트를 가져온 다음 해당 스크립트에 정의된 개체가 데이터베이스 프로젝트에 추가됩니다.

  5. 요약을 검토한 다음 마침을 클릭하여 작업을 완료합니다.

    참고

    Sales.uspFillOrder 프로시저에는 이 절차의 뒷부분에서 검색하여 수정할 의도적인 코딩 오류가 있습니다.

결과 프로젝트를 검사하려면

  1. 솔루션 탐색기에서 스키마 개체 자식 노드를 확장합니다.

  2. 계층 구조에서 스키마 개체 노드 아래에 있는 하위 노드를 탐색합니다.

    솔루션 탐색기에는 데이터베이스 개체를 정의하는 파일이 포함됩니다.

  3. 보기 메뉴에서 데이터베이스 스키마 뷰를 클릭합니다.

  4. 스키마 뷰에서 SimpleUnitTestDB 노드를 확장합니다.

  5. 계층 구조에서 SimpleUnitTestDB 노드 아래에 있는 하위 노드를 탐색합니다.

    스키마 뷰에는 솔루션 탐색기에 나타나는 파일에 정의되어 있는 개체가 포함됩니다.

격리된 개발 환경에 배포

다음에는 프로젝트를 배포하여 가져온 스키마만 있고 데이터는 없는 데이터베이스를 만듭니다. 다른 작업으로 인한 방해를 받지 않고 데이터베이스를 개발하고 테스트할 수 있도록 격리된 개발 환경(또는 샌드박스)에서 이 데이터베이스를 만듭니다.

데이터베이스 프로젝트를 구성하고 빌드하려면

  1. 솔루션 탐색기에서 데이터베이스 프로젝트 SimpleUnitTestDB를 클릭합니다.

  2. 프로젝트 메뉴에서 SimpleUnitTestDB 속성을 클릭합니다.

    프로젝트의 속성 대화 상자가 나타납니다.

  3. 배포 탭을 클릭합니다.

  4. 배포 설정 구성 목록에서 내 격리된 개발 환경을 클릭합니다. 격리된 개발 환경의 설정을 구성하면 스테이징 또는 프로덕션 서버 등의 다른 환경에서 사용할 설정과는 다른 배포 설정을 사용할 수 있습니다.

  5. 배포 작업 목록에서 배포 스크립트(.sql)를 만들고 데이터베이스에 배포를 클릭합니다.

  6. 대상 데이터베이스 설정에서 편집을 클릭합니다.

    연결 속성 대화 상자가 표시됩니다.

  7. 만들려는 데이터베이스에 대한 연결 속성을 설정한 다음 확인을 클릭합니다.

    대상 연결 상자에 올바른 연결 문자열이 표시됩니다.

    경고

    테스트 서버, 개발 서버 또는 로컬 컴퓨터에서 데이터베이스를 만들어야 합니다. 프로덕션 서버를 지정하면 안 됩니다.

  8. 대상 데이터베이스 이름에 SimpleUnitTestDB를 입력합니다.

  9. 배포 구성 파일 옆의 편집을 클릭합니다.

  10. 데이터가 손실되면 증분 배포 차단 확인란의 선택을 취소합니다.

    참고

    이 연습에서는 데이터베이스 단위 테스트의 일부로 배포하는 빈 데이터베이스에 대해 저장 프로시저를 테스트합니다. 격리된 개발 환경에서 저장 프로시저를 테스트하므로 기존 데이터를 유지할 필요는 없습니다.

  11. 파일 메뉴에서 모두 저장을 클릭합니다.

  12. 빌드 메뉴에서 솔루션 빌드를 클릭합니다.

    방금 설정한 속성에 따라 배포 스크립트가 빌드되는 방식이 결정됩니다. 출력 창에 빌드 상태가 표시되고 빌드: 성공 또는 최신 상태 1이 마지막 줄에 표시되어야 합니다.

    참고

    출력 창이 나타나지 않는 경우 보기 메뉴를 열고 출력을 클릭합니다.

데이터베이스 프로젝트를 배포하려면

  1. 솔루션 탐색기에서 데이터베이스 프로젝트 SimpleUnitTestDB를 클릭합니다.

  2. 빌드 메뉴에서 SimpleUnitTestDB 배포를 클릭합니다.

    경고

    테스트 서버, 개발 서버 또는 로컬 컴퓨터에 대해 이 배포를 실행해야 합니다. 프로덕션 서버를 지정하면 안 됩니다.

    데이터베이스 프로젝트가 새 데이터베이스로 배포됩니다. 출력 창에 배포 상태가 표시되고, 마지막 줄로 배포: 성공 1이 표시되어야 합니다. 데이터 생성 계획을 정의하여 데이터베이스에 테스트 데이터를 만들 수도 있습니다. 이 연습에서는 데이터를 생성할 필요가 없는 아주 간단한 데이터베이스를 테스트합니다.

데이터베이스 단위 테스트 만들기

저장 프로시저용 데이터베이스 단위 테스트를 만들려면

  1. 보기 메뉴에서 데이터베이스 스키마 뷰를 클릭합니다.

  2. 스키마 뷰에서 스키마 노드, Sales 노드, 프로그래밍 기능 노드, 저장 프로시저 노드를 차례로 확장합니다.

  3. uspNewCustomer 저장 프로시저를 마우스 오른쪽 단추로 클릭하고 단위 테스트 만들기를 클릭합니다.

    단위 테스트 만들기 대화 상자가 표시됩니다.

  4. 다섯 개의 저장 프로시저, 즉 Sales.uspCancelOrder, Sales.uspFillOrder, Sales.uspNewCustomer, Sales.uspPlaceNewOrderSales.uspShowOrderDetails의 확인란을 모두 선택합니다.

  5. 프로젝트에서 새 Visual C# 테스트 프로젝트 만들기를 클릭합니다.

  6. 프로젝트 이름 및 클래스 이름의 기본 이름을 그대로 적용하고 확인을 클릭합니다.

    프로젝트 'TestProject1' 구성 대화 상자가 나타납니다.

  7. 다음 데이터 연결을 사용하여 단위 테스트 실행에서 이 연습의 앞부분에서 배포한 데이터베이스에 대한 연결을 지정합니다.

    참고

    사용 권한이 제한된 뷰 또는 저장 프로시저를 테스트해야 하는 경우 일반적으로 이 단계에서 해당 연결을 지정합니다. 그런 다음 보다 광범위한 권한으로 보조 연결을 지정하여 테스트의 유효성을 검사합니다. 보조 연결이 있는 경우에는 해당 사용자를 데이터베이스 프로젝트에 추가하고 배포 전 스크립트에 해당 사용자에 대한 로그인을 만들어야 합니다.

  8. 배포에서 단위 테스트를 실행하기 전에 데이터베이스 프로젝트를 자동으로 배포 확인란을 선택합니다.

  9. 데이터베이스 프로젝트에서 SimpleUnitTestDB.dbproj를 클릭합니다.

  10. 배포 구성에서 디버그를 클릭합니다.

    데이터베이스 단위 테스트의 일부로 테스트 데이터를 생성할 수도 있습니다. 이 연습에서는 테스트 자체에서 고유한 데이터가 만들어지므로 이 단계는 건너뜁니다.

  11. 확인을 클릭합니다.

    테스트 프로젝트가 빌드되고 데이터베이스 단위 테스트 디자이너가 나타납니다. 다음에는 단위 테스트의 Transact-SQL 스크립트에서 테스트 논리를 업데이트합니다.

테스트 논리 정의

매우 간단한 이 데이터베이스에는 Customer와 Order라는 두 개의 테이블이 있습니다. 다음 저장 프로시저를 사용하여 이 데이터베이스를 업데이트합니다.

  • uspNewCustomer - 이 저장 프로시저는 Customer 테이블에 고객의 YTDOrders 및 YTDSales 열을 0으로 설정하는 레코드를 추가합니다.

  • uspPlaceNewOrder - 이 저장 프로시저는 지정된 고객의 Orders 테이블에 레코드를 추가하고 Customer 테이블의 해당 레코드에서 YTDOrders 값을 업데이트합니다.

  • uspFillOrder - 이 저장 프로시저는 Orders 테이블의 레코드를 'O' 상태에서 'F' 상태로 변경하여 업데이트하고 Customer 테이블의 해당 레코드에서 YTDSales 금액을 증가시킵니다.

  • uspCancelOrder - 이 저장 프로시저는 Orders 테이블의 레코드를 'O' 상태에서 'X' 상태로 변경하여 업데이트하고 Customer 테이블의 해당 레코드에서 YTDOrders 금액을 감소시킵니다.

  • uspShowOrderDetails - 이 저장 프로시저는 Orders 테이블과 Custom 테이블을 조인하고 특정 고객에 대한 레코드를 표시합니다.

참고

이 예제에서는 간단한 데이터베이스 단위 테스트를 만드는 방법을 보여 줍니다. 실제 데이터베이스에서는 특정 고객에 대해 상태가 'O' 또는 'F'인 모든 주문의 총 금액을 합산할 수 있습니다. 이 연습의 절차에는 오류 처리도 포함되어 있지 않습니다. 예를 들어 이미 이행된 주문에 대해 uspFillOrder를 호출할 수 있습니다.

이 테스트에서는 데이터베이스가 정리된 상태로 시작된다고 가정합니다. 다음 조건을 확인하는 테스트를 만듭니다.

  • uspNewCustomer - 저장 프로시저를 실행한 후 Customer 테이블에 하나의 행이 있는지 확인합니다.

  • uspPlaceNewOrder - CustomerID가 1인 고객에 대해 $100의 주문을 넣습니다. 이 고객의 YTDOrders 금액이 100이며 YTDSales 금액이 0인지 확인합니다.

  • uspFillOrder - CustomerID가 1인 고객에 대해 $50의 주문을 넣습니다. 해당 주문을 이행합니다. YTDOrders와 YTDSales의 금액이 모두 50인지 확인합니다.

  • uspShowOrderDetails - CustomerID가 1인 고객에 대해 $100, $50 및 $5의 주문을 넣습니다. uspShowOrderDetails에서 올바른 열 수를 반환하고 결과 집합에 예상 체크섬이 있는지 확인합니다.

참고

전체 데이터베이스 단위 테스트 집합의 경우 일반적으로는 다른 열이 올바르게 설정되었는지 확인하게 됩니다. 이 연습을 관리 가능한 크기로 유지하기 위해 이 연습에서는 uspCancelOrder의 동작을 확인하는 방법을 설명하지 않습니다.

uspNewCustomer에 대한 데이터베이스 단위 테스트를 작성하려면

  1. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspNewCustomerTest를 클릭하고 인접한 목록에서 테스트가 강조 표시되어 있는지 확인합니다.

    앞의 단계를 수행한 후에는 단위 테스트에서 테스트 작업에 대한 테스트 스크립트를 만들 수 있습니다.

  2. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    -- database unit test for Sales.uspNewCustomer
    DECLARE @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @CustomerName = 'Fictitious Customer';
    
    EXECUTE @RC = [Sales].[uspNewCustomer] @CustomerName;
    
    SELECT * FROM [Sales].[Customer];
    
  3. 테스트 조건 창에서 결과 불충분 테스트 조건을 클릭한 다음 테스트 조건 삭제(x)를 클릭합니다.

  4. 테스트 조건 창의 목록에서 행 개수를 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  5. 속성 창에서 행 개수 속성을 1로 설정합니다.

  6. 파일 메뉴에서 모두 저장을 클릭합니다.

    다음에는 uspPlaceNewOrder에 대한 단위 테스트 논리를 정의합니다.

uspPlaceNewOrder에 대한 데이터베이스 단위 테스트를 작성하려면

  1. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspPlaceNewOrderTest를 클릭하고 인접한 목록에서 테스트가 강조 표시되어 있는지 확인합니다.

    이 단계를 수행한 후에는 단위 테스트에서 테스트 작업에 대한 테스트 스크립트를 만들 수 있습니다.

  2. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    -- database unit test for Sales.uspPlaceNewOrder
    DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1);
    DECLARE @CustomerName AS NVARCHAR(40);
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @OrderDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- place an order for that customer
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status;
    
    -- verify that the YTDOrders value is correct.
    SELECT @RC = [YTDOrders] FROM [Sales].[Customer] WHERE [CustomerID] = @CustomerID
    
    SELECT @RC AS RC
    
  3. 테스트 조건 창에서 결과 불충분 테스트 조건을 클릭하고 테스트 조건 삭제(x)를 클릭합니다.

  4. 테스트 조건 창의 목록에서 스칼라 값을 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  5. 속성 창에서 예상 값 속성을 100으로 설정합니다.

  6. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspPlaceNewOrderTest를 클릭하고 인접한 목록에서 테스트 전이 강조 표시되어 있는지 확인합니다.

    이 단계를 수행한 후에는 데이터를 테스트 실행에 필요한 상태로 만드는 문을 지정할 수 있습니다. 이 예제의 경우 먼저 고객 레코드를 만들어야 주문을 할 수 있습니다.

  7. **만들려면 여기를 클릭합니다.**를 클릭하여 테스트 전 스크립트를 만듭니다.

  8. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    /*
    Add Transact-SQL statements here that you want to run before
    the test script is run.
    */
    -- Add a customer for this test with the name 'Fictitious Customer'
    DECLARE @NewCustomerID AS INT, @CustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @NewCustomerID = 0,
       @CustomerID = 0,
           @CustomerName = N'Fictitious Customer';
    
    IF NOT EXISTS(SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName)
    BEGIN
    EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName;
    END
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields
    DELETE from [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;
    
  9. 파일 메뉴에서 모두 저장을 클릭합니다.

    다음에는 uspFillOrder에 대한 단위 테스트를 만듭니다.

uspFillOrder에 대한 데이터베이스 단위 테스트를 작성하려면

  1. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspFillOrderTest를 클릭하고 인접한 목록에서 테스트가 강조 표시되어 있는지 확인합니다.

    이 단계를 수행한 후에는 단위 테스트에서 테스트 작업에 대한 테스트 스크립트를 만들 수 있습니다.

  2. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    -- database unit test for Sales.uspFillOrder
    DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1);
    DECLARE @CustomerName AS NVARCHAR(40), @OrderID AS INT;
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @OrderID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @FilledDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    -- Get the most recently added order.
    SELECT @OrderID = MAX([OrderID]) FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    
    -- fill an order for that customer
    EXECUTE @RC = [Sales].[uspFillOrder] @OrderID, @FilledDate;
    
    -- verify that the YTDOrders value is correct.
    SELECT @RC = [YTDSales] FROM [Sales].[Customer] WHERE [CustomerID] = @CustomerID
    
    SELECT @RC AS RC;
    
  3. 테스트 조건 창에서 결과 불충분 테스트 조건을 클릭하고 테스트 조건 삭제(x)를 클릭합니다.

  4. 테스트 조건 창의 목록에서 스칼라 값을 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  5. 속성 창에서 예상 값 속성을 100으로 설정합니다.

  6. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspFillOrderTest를 클릭하고 인접한 목록에서 테스트 전이 강조 표시되어 있는지 확인합니다. 이 단계를 수행한 후에는 데이터를 테스트 실행에 필요한 상태로 만드는 문을 지정할 수 있습니다. 이 예제의 경우 먼저 고객 레코드를 만들어야 주문을 할 수 있습니다.

  7. **만들려면 여기를 클릭합니다.**를 클릭하여 테스트 전 스크립트를 만듭니다.

  8. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    /*
    Add Transact-SQL statements here that you want to run before
    the test script is run.
    */
    BEGIN TRANSACTION
    
    -- Add a customer for this test with the name 'CustomerB'
    DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @NewCustomerID = 0,
           @CustomerName = N'Fictitious Customer';
    
    IF NOT EXISTS(SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName)
    BEGIN
    EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName;
    END
    
    DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1);
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @OrderDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields
    DELETE from [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;
    
    -- place an order for that customer
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status;
    
    COMMIT TRANSACTION
    
  9. 파일 메뉴에서 모두 저장을 클릭합니다.

    이제 테스트를 실행할 준비가 되었습니다.

uspShowOrderDetails에 대한 데이터베이스 단위 테스트를 작성하려면

  1. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspShowOrderDetailsTest를 클릭하고 인접한 목록에서 테스트가 강조 표시되어 있는지 확인합니다.

    이 단계를 수행한 후에는 단위 테스트에서 테스트 작업에 대한 테스트 스크립트를 만들 수 있습니다.

  2. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    -- database unit test for Sales.uspFillOrder
    DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1);
    DECLARE @CustomerName AS NVARCHAR(40), @OrderID AS INT;
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @OrderID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @FilledDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- fill an order for that customer
    EXECUTE @RC = [Sales].[uspShowOrderDetails] @CustomerID;
    
    SELECT @RC AS RC;
    
  3. 테스트 조건 창에서 결과 불충분 테스트 조건을 클릭하고 테스트 조건 삭제(x)를 클릭합니다.

  4. 테스트 조건 창의 목록에서 필요한 스키마를 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  5. 속성 창의 구성 속성에서 찾아보기 단추('')를 클릭합니다.

  6. expectedSchemaCondition1에 대한 구성 대화 상자에서 데이터베이스에 대한 연결을 지정합니다.

  7. 검색을 클릭합니다.

    단위 테스트의 Transact-SQL 본문이 실행되고 결과 스키마가 대화 상자에 표시됩니다. 테스트 전 코드는 실행되지 않았으므로 데이터가 반환되지 않습니다. 이 연습에서는 스키마만 확인하고 데이터는 확인하지 않으므로 문제가 되지 않습니다.

  8. 확인을 클릭합니다.

    예상 스키마가 테스트 조건과 함께 저장됩니다.

  9. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspShowOrderDetailsTest를 클릭하고 인접한 목록에서 테스트 전이 강조 표시되어 있는지 확인합니다. 이 단계를 수행한 후에는 데이터를 테스트 실행에 필요한 상태로 만드는 문을 지정할 수 있습니다. 이 예제의 경우 먼저 고객 레코드를 만들어야 주문을 할 수 있습니다.

  10. **만들려면 여기를 클릭합니다.**를 클릭하여 테스트 전 스크립트를 만듭니다.

  11. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    /*
    Add Transact-SQL statements here that you want to run before
    the test script is run.
    */
    BEGIN TRANSACTION
    
    -- Add a customer for this test with the name 'FictitiousCustomer'
    DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @NewCustomerID = 0,
           @CustomerName = N'Fictitious Customer';
    
    IF NOT EXISTS(SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName)
    BEGIN
    EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName;
    END
    
    
    DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1);
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @CustomerName = N'Fictitious Customer',
           @OrderDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields
    DELETE from [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;
    
    -- place 3 orders for that customer
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, @OrderDate, @Status;
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 50, @OrderDate, @Status;
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 5, @OrderDate, @Status;
    
    COMMIT TRANSACTION
    
  12. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspShowOrderDetailsTest를 클릭하고 인접한 목록에서 테스트를 클릭합니다.

    사전 테스트가 아니라 테스트에 체크섬 조건을 적용하려고 하므로 이 작업을 수행해야 합니다.

  13. 테스트 조건 창의 목록에서 데이터 체크섬을 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  14. 속성 창의 구성 속성에서 찾아보기 단추('')를 클릭합니다.

  15. checksumCondition1에 대한 구성 대화 상자에서 데이터베이스에 대한 연결을 지정합니다.

  16. 대화 상자의 Transact-SQL을 다음 코드로 바꿉니다.

    BEGIN TRANSACTION
    
    -- Add a customer for this test with the name 'CustomerB'
    DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @NewCustomerID = 0,
           @CustomerName = N'Fictitious Customer';
    
    IF NOT EXISTS(SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName)
    BEGIN
    EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName;
    END
    
    
    DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1);
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @CustomerName = N'Fictitious Customer',
           @OrderDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields
    DELETE from [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;
    
    
    
    -- place 3 orders for that customer
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, @OrderDate, @Status;
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 50, @OrderDate, @Status;
    EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 5, @OrderDate, @Status;
    
    
    COMMIT TRANSACTION
    
    
    -- database unit test for Sales.uspFillOrder
    DECLARE @FilledDate AS DATETIME;
    DECLARE @OrderID AS INT;
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @OrderID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @FilledDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- fill an order for that customer
    EXECUTE @RC = [Sales].[uspShowOrderDetails] @CustomerID;
    
    SELECT @RC AS RC;
    

    이 코드는 사전 테스트의 Transact-SQL 코드와 테스트 자체의 Transact-SQL을 조합한 코드입니다. 테스트를 실행할 때 테스트에서 반환되는 것과 동일한 결과가 반환되도록 하려면 두 코드가 모두 필요합니다.

  17. 검색을 클릭합니다.

    지정한 Transact-SQL이 실행되고 반환된 데이터에 대한 체크섬이 계산됩니다.

  18. 확인을 클릭합니다.

    계산된 체크섬이 테스트 조건과 함께 저장됩니다. 예상 체크섬이 데이터 체크섬 테스트 조건의 값 열에 표시됩니다.

  19. 파일 메뉴에서 모두 저장을 클릭합니다.

    이제 테스트를 실행할 준비가 되었습니다.

데이터베이스 단위 테스트 실행

데이터베이스 단위 테스트를 실행하려면

  1. 테스트 메뉴에서 을 가리킨 다음 테스트 뷰를 클릭합니다.

  2. 테스트 뷰 창의 도구 모음에서 새로 고침을 클릭하여 테스트 목록을 업데이트합니다.

    이 연습의 앞부분에서 만들고 Transact-SQL 문 및 테스트 조건을 추가한 테스트가 테스트 뷰 창에 나열됩니다. TestMethod1이라는 테스트는 비어 있으며 이 연습에서 사용하지 않습니다.

  3. Sales_uspNewCustomerTest를 마우스 오른쪽 단추로 클릭하고 선택 항목 실행을 클릭합니다.

    Visual Studio에서는 사용자가 지정한 권한 있는 컨텍스트를 사용하여 데이터베이스에 연결하고 데이터 생성 계획을 적용합니다. 그런 다음 Visual Studio는 테스트에서 Transact-SQL 스크립트를 실행하기 전에 실행 컨텍스트로 전환합니다. 마지막으로, Visual Studio에서는 Transact-SQL 스크립트의 결과를 테스트 조건에 지정된 스크립트와 비교하여 확인하며 결과(통과/실패 여부)는 테스트 결과 창에 표시됩니다.

  4. 테스트 결과 창에서 결과를 확인합니다.

    테스트가 통과되면 SELECT 문을 실행할 때 한 개의 행이 반환된 것입니다.

  5. Sales_uspPlaceNewOrderTest, Sales_uspFillOrderTest 및 Sales_uspShowOrderDetailsTest 테스트에 대해 3단계를 반복합니다. 결과는 다음과 같아야 합니다.

    테스트

    예상 결과

    Sales_uspPlaceNewOrderTest

    통과

    Sales_uspShowOrderDetailsTest

    통과

    Sales_uspFillOrderTest

    실패. "ScalarValueCondition 조건(scalarValueCondition2) 실패: 결과 집합 1 행 1 열 1: 값이 일치하지 않습니다. '100'이(가) 필요한데 '-100'입니다."라는 오류가 발생합니다. 이 오류는 저장 프로시저의 정의에 사소한 오류가 있기 때문에 발생합니다.

    다음에는 오류를 해결하고 테스트를 다시 실행합니다.

Sales.uspFillOrder의 오류를 해결하려면

  1. 스키마 뷰에서 uspFillOrder 저장 프로시저를 두 번 클릭하여 Transact-SQL 편집기에서 해당 정의를 엽니다.

  2. 정의에서 다음 Transact-SQL 문을 찾습니다.

    UPDATE [Sales].[Customer]
       SET
       YTDSales = YTDSales - @Delta
        WHERE [CustomerID] = @CustomerID
    
  3. 다음 문과 일치하도록 문의 SET 절을 변경합니다.

    UPDATE [Sales].[Customer]
       SET
       YTDSales = YTDSales + @Delta
        WHERE [CustomerID] = @CustomerID
    
  4. 파일 메뉴에서 uspFillOrder.proc.sql 저장을 클릭합니다.

  5. 테스트 뷰에서 Sales_uspFillOrderTest를 마우스 오른쪽 단추로 클릭한 다음 선택 항목 실행을 클릭합니다.

    테스트가 통과됩니다.

부정적 단위 테스트 추가

부정적 테스트를 만들어 실패해야 하는 테스트가 실제로 실패하는지 확인할 수 있습니다. 예를 들어 이미 이행된 주문을 취소하려고 하면 해당 테스트가 실패해야 합니다. 이 연습 부분에서는 Sales.uspCancelOrder 저장 프로시저에 대한 부정적 단위 테스트를 만듭니다.

부정적 테스트를 만들고 확인하려면 다음 작업을 수행해야 합니다.

  • 저장 프로시저를 업데이트하여 실패 조건 테스트

  • 새 단위 테스트 정의

  • 예상된 실패임을 나타내도록 단위 테스트에 대한 코드 수정

  • 단위 테스트 실행

저장 프로시저를 업데이트하려면

  1. 스키마 뷰에서 SimpleUnitTestDB 노드, 스키마 노드, Sales 노드, 프로그래밍 기능 노드, 저장 프로시저 노드를 차례로 확장하고 uspCancelOrder를 두 번 클릭합니다.

  2. Transact-SQL 편집기에서 다음 코드와 일치하도록 프로시저 정의를 업데이트합니다.

    CREATE PROCEDURE [Sales].[uspCancelOrder]
    @OrderID INT
    AS
    BEGIN
        DECLARE @Delta INT, @CustomerID INT, @PriorStatus CHAR(1)
        BEGIN TRANSACTION
            BEGIN TRY
                IF (NOT EXISTS(SELECT [CustomerID] from [Sales].[Orders] WHERE [OrderID] = @OrderID))
                BEGIN
                    -- Specify WITH LOG option so that the error is
                    -- written to the application log.
                    RAISERROR( 'That order does not exist.', -- Message text
                               16, -- severity
                                1 -- state
                            ) WITH LOG;
                END
    
                SELECT @Delta = [Amount], @CustomerID = [CustomerID], @PriorStatus = [Status]
                 FROM [Sales].[Orders] WHERE [OrderID] = @OrderID
    
                IF @PriorStatus <> 'O' 
                BEGIN
                    -- Specify WITH LOG option so that the error is
                    -- written to the application log.
                    RAISERROR ( 'You can only cancel open orders.', -- Message text
                                16, -- Severity
                                1 -- State
                                ) WITH LOG;
                END
                ELSE
                BEGIN
                    -- If we make it to here, then we can cancel the order. Update the status to 'X' first...
                    UPDATE [Sales].[Orders]
                       SET [Status] = 'X'
                    WHERE [OrderID] = @OrderID
                    -- and then remove the amount from the YTDOrders for the customer
                    UPDATE [Sales].[Customer]
                           SET
                               YTDOrders = YTDOrders - @Delta
                    WHERE [CustomerID] = @CustomerID
                    COMMIT TRANSACTION
                    RETURN 1; -- indicate success
                END
            END TRY
            BEGIN CATCH
                DECLARE @ErrorMessage NVARCHAR(4000);
                DECLARE @ErrorSeverity INT;
                DECLARE @ErrorState INT;
    
                SELECT @ErrorMessage = ERROR_MESSAGE(),
                       @ErrorSeverity = ERROR_SEVERITY(),
                       @ErrorState = ERROR_STATE();
    
                ROLLBACK TRANSACTION
                -- Use RAISERROR inside the CATCH block to return
                -- error information about the original error that
                -- caused execution to jump to the CATCH block.
                RAISERROR (@ErrorMessage, -- Mesasge text
                           @ErrorSeverity, -- Severity
                           @ErrorState -- State
                          );
                RETURN 0; -- indicate failure
            END CATCH;
    END
    
  3. 파일 메뉴에서 uspCancelOrder.proc.sql 저장을 클릭합니다.

  4. 솔루션 탐색기에서 SimpleUnitTestDB를 마우스 오른쪽 단추로 클릭하고 배포를 클릭합니다.

    uspCancelOrder 저장 프로시저에 업데이트가 배포됩니다. 다른 개체는 변경하지 않았으므로 해당 저장 프로시저만 업데이트됩니다.

    다음에는 이 프로시저에 대한 관련 단위 테스트를 정의합니다.

uspCancelOrder에 대한 데이터베이스 단위 테스트를 작성하려면

  1. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspCancelOrderTest를 클릭하고 인접한 목록에서 테스트가 강조 표시되어 있는지 확인합니다.

    이 단계를 수행한 후에는 단위 테스트에서 테스트 작업에 대한 테스트 스크립트를 만들 수 있습니다.

  2. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    -- database unit test for Sales.uspFillOrder
    DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1);
    DECLARE @CustomerName AS NVARCHAR(40), @OrderID AS INT;
    
    SELECT @RC = 0,
           @CustomerID = 0,
           @OrderID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @FilledDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    -- Get the most recently added order.
    SELECT @OrderID = MAX([OrderID]) FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    
    -- try to cancel an order for that customer that has already been filled
    EXECUTE @RC = [Sales].[uspCancelOrder] @OrderID;
    
    SELECT @RC AS RC;
    
  3. 테스트 조건 창에서 결과 불충분 테스트 조건을 클릭하고 테스트 조건 삭제(x)를 클릭합니다.

  4. 테스트 조건 창의 목록에서 스칼라 값을 클릭한 다음 테스트 조건 추가(+)를 클릭합니다.

  5. 속성 창에서 예상 값 속성을 0으로 설정합니다.

  6. 데이터베이스 단위 테스트 디자이너의 탐색 모음에서 Sales_uspCancelOrderTest를 클릭하고 인접한 목록에서 테스트 전이 강조 표시되어 있는지 확인합니다. 이 단계를 수행한 후에는 데이터를 테스트 실행에 필요한 상태로 만드는 문을 지정할 수 있습니다. 이 예제의 경우 먼저 고객 레코드를 만들어야 주문을 할 수 있습니다.

  7. **만들려면 여기를 클릭합니다.**를 클릭하여 테스트 전 스크립트를 만듭니다.

  8. Transact-SQL 편집기에서 다음 문과 일치하도록 Transact-SQL 문을 업데이트합니다.

    /*
    Add Transact-SQL statements here that you want to run before
    the test script is run.
    */
    BEGIN TRANSACTION
    
    -- Add a customer for this test with the name 'CustomerB'
    DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40);
    
    SELECT @RC = 0,
           @NewCustomerID = 0,
           @CustomerName = N'Fictitious Customer';
    
    IF NOT EXISTS(SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName)
    BEGIN
    EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName;
    END
    
    DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @FilledDate AS DATETIME, @Status AS CHAR (1), @OrderID AS INT;
    
    SELECT @RC = 0,
           @CustomerID = 0,
       @OrderID = 0,
           @CustomerName = N'Fictitious Customer',
           @Amount = 100,
           @OrderDate = getdate(),
       @FilledDate = getdate(),
           @Status = 'O';
    
    -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script.
    SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName;
    
    -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields
    DELETE from [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
    UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;
    
    -- place an order for that customer
    EXECUTE @OrderID = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status;
    
    -- fill the order for that customer
    EXECUTE @RC = [Sales].[uspFillOrder] @OrderID, @FilledDate;
    
    COMMIT TRANSACTION
    
  9. 파일 메뉴에서 모두 저장을 클릭합니다.

    이제 테스트를 실행할 준비가 되었습니다.

데이터베이스 단위 테스트를 실행하려면

  1. 테스트 뷰에서 Sales_uspCancelOrderTest를 마우스 오른쪽 단추로 클릭한 다음 선택 항목 실행을 클릭합니다.

  2. 테스트 결과 창에서 결과를 확인합니다.

    테스트가 실패하고 다음 오류가 나타납니다.

    Test method TestProject1.DatabaseUnitTests1.Sales_uspCancelOrderTest threw exception: System.Data.SqlClient.SqlException: You can only cancel open orders.

    다음에는 예외가 예상된 것임을 나타내도록 코드를 수정합니다.

단위 테스트에 대한 코드를 수정하려면

  1. 솔루션 탐색기에서 TestProject1을 확장하고 DatabaseUnitTests1.cs를 마우스 오른쪽 단추로 클릭한 다음 코드 보기를 클릭합니다.

  2. 코드 편집기에서 Sales_uspCancelOrderTest 메서드로 이동합니다. 다음 코드와 일치하도록 메서드 특성을 수정합니다.

            [TestMethod(), ExpectedSqlException(Severity=16, MatchFirstError=false, State=1)]
            public void Sales_uspCancelOrderTest()
    

    특정 SQL 예외를 표시하도록 지정합니다. 경우에 따라 특정 오류 번호를 지정할 수 있습니다. 이 특성을 추가하지 않으면 단위 테스트가 실패하고 테스트 결과 창에 메시지가 나타납니다.

  3. 파일 메뉴에서 DatabaseUnitTests1.cs 저장을 클릭합니다.

    다음에는 단위 테스트를 다시 실행하여 테스트가 예상대로 실패하는지 확인합니다.

데이터베이스 단위 테스트를 다시 실행하려면

  1. 테스트 뷰에서 Sales_uspCancelOrderTest를 마우스 오른쪽 단추로 클릭한 다음 선택 항목 실행을 클릭합니다.

  2. 테스트 결과 창에서 결과를 확인합니다.

    테스트가 통과되면 실패해야 하는 프로시저가 실패한 것입니다.

다음 단계

일반적인 프로젝트의 경우에는 모든 주요 데이터베이스 개체가 제대로 작동하는지 확인하기 위해 추가 단위 테스트를 정의합니다. 일련의 테스트가 완료되면 테스트를 팀과 공유할 수 있도록 버전 제어에 체크 인합니다.

기준을 지정한 후에는 데이터베이스 개체를 만들고 수정한 다음 연관된 테스트를 만들어 변경 내용으로 인해 예상 동작이 중단되는지 여부를 확인합니다.

참고 항목

작업

방법: 빈 데이터베이스 단위 테스트 만들기

방법: 데이터베이스 단위 테스트 실행 구성

개념

데이터베이스 단위 테스트 만들기 및 정의

단위 테스트를 사용하여 데이터베이스 코드 확인

데이터 생성기를 사용하여 데이터베이스의 테스트 데이터 생성