방법: 단일 트랜잭션 범위 내에서 실행되는 데이터베이스 단위 테스트 작성

이 항목은 다음 언어에 적용됩니다.

Visual Studio Ultimate

Visual Studio Premium

Visual Studio 2010 Professional 

Visual Studio Express

항목이 적용됨 항목이 적용됨 항목이 적용되지 않음 항목이 적용되지 않음

단일 트랜잭션 범위 내에서 실행되도록 단위 테스트를 수정할 수 있습니다. 이 접근 방식을 사용하면 테스트가 끝난 후에 테스트에서 수행했던 모든 변경 내용을 롤백할 수 있습니다. 다음 절차에서는 아래 작업을 수행하는 방법에 대해 설명합니다.

  • BEGIN TRANSACTION 및 ROLLBACK TRANSACTION을 사용하는 Transact-SQL 테스트 스크립트에서 트랜잭션을 만듭니다.

  • 테스트 클래스의 단일 테스트 메서드에 대한 트랜잭션을 만듭니다.

  • 지정된 테스트 클래스의 모든 테스트 메서드에 대한 트랜잭션을 만듭니다.

사전 요구 사항

이 항목에 소개된 일부 절차의 경우 단위 테스트를 수행하는 컴퓨터에 DTC(Distributed Transaction Coordinator) 서비스가 실행되고 있어야 합니다. 자세한 내용은 이 항목의 끝에 나오는 절차를 참조하십시오.

Transact-SQL을 사용하여 트랜잭션을 만들려면

Transact-SQL을 사용하여 트랜잭션을 만들려면

  1. 데이터베이스 단위 테스트 디자이너에서 단위 테스트를 엽니다.

  2. 트랜잭션을 만들 스크립트의 형식을 지정합니다. 예를 들어 테스트 전, 테스트 또는 테스트 후를 지정할 수 있습니다.

  3. Transact-SQL 편집기에서 테스트 스크립트를 입력합니다.

  4. 다음의 간단한 예제와 같이 BEGIN TRANSACTION 및 ROLLBACK TRANSACTION 문을 삽입합니다. 이 예제에서는 50개의 데이터 행이 포함된 OrderDetails라는 데이터베이스 테이블을 사용합니다.

    BEGIN TRANSACTION TestTransaction
    UPDATE "OrderDetails" set Quantity = Quantity + 10
    IF @@ROWCOUNT!=50
    RAISERROR('Row count does not equal 50',16,1)
    ROLLBACK TRANSACTION TestTransaction
    

    참고

    COMMIT TRANSACTION 문이 실행된 후에는 트랜잭션을 롤백할 수 없습니다.

    ROLLBACK TRANSACTION이 저장 프로시저 및 트리거에서 사용되는 방식에 대한 자세한 내용은 Microsoft 웹 사이트에서 ROLLBACK TRANSACTION(Transact-SQL) 페이지를 참조하십시오.

단일 테스트 메서드에 대한 트랜잭션을 만들려면

이 예제에서는 TransactionScope 형식을 사용할 때 앰비언트 트랜잭션을 사용합니다. 실행 및 권한 있는 연결은 메서드가 실행되기 전에 만들어졌으므로 이러한 연결에서는 기본적으로 앰비언트 트랜잭션이 사용되지 않습니다. SqlConnection의 EnlistTransaction 메서드는 활성 연결과 트랜잭션을 연결합니다. 앰비언트 트랜잭션이 만들어지면 현재 트랜잭션으로 등록되어 Current 속성을 통해 액세스할 수 있습니다. 이 예제에서는 앰비언트 트랜잭션이 삭제되면 이 트랜잭션이 롤백됩니다. 단위 테스트 실행 시 발생한 변경 내용을 커밋하려면 Complete 메서드를 호출해야 합니다.

단일 테스트 메서드에 대한 트랜잭션을 만들려면

  1. 솔루션 탐색기에서 테스트 프로젝트의 참조 노드를 마우스 오른쪽 단추로 클릭하고 참조 추가를 클릭합니다.

    참조 추가 대화 상자가 나타납니다.

  2. .NET 탭을 클릭합니다.

  3. 어셈블리 목록에서 System.Transactions를 클릭하고 확인을 클릭합니다.

  4. 단위 테스트에 대한 Visual Basic 또는 C# 파일을 엽니다.

  5. 다음 Visual Basic 코드 예제와 같이 테스트 전, 테스트 및 테스트 후 작업을 래핑합니다.

        <TestMethod()> _
        Public Sub dbo_InsertTable1Test()
    
            Using ts as New System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required)
                ExecutionContext.Connection.EnlistTransaction(Transaction.Current)
                PrivilegedContext.Connection.EnlistTransaction(Transaction.Current)
    
                Dim testActions As DatabaseTestActions = Me.dbo_InsertTable1TestData
                'Execute the pre-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PretestAction) Is Nothing), "Executing pre-test script...")
                Dim pretestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PretestAction)
                'Execute the test script
    
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.TestAction) Is Nothing), "Executing test script...")
                Dim testResults() As ExecutionResult = TestService.Execute(ExecutionContext, Me.PrivilegedContext, testActions.TestAction)
    
                'Execute the post-test script
                '
                System.Diagnostics.Trace.WriteLineIf((Not (testActions.PosttestAction) Is Nothing), "Executing post-test script...")
                Dim posttestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PosttestAction)
    
                'Because the transaction is not explicitly committed, it
                'is rolled back when the ambient transaction is 
                'disposed.
                'To commit the transaction, remove the comment delimiter
                'from the following statement:
                'ts.Complete()
    
        End Sub
        Private dbo_InsertTable1TestData As DatabaseTestActions
    

    참고

    Visual Basic을 사용하는 경우 Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 및 Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions와 함께 Imports System.Transactions를 추가해야 합니다. Visual C#을 사용하는 경우에는 Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting 및 Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions에 대한 using 문과 함께 using System.Transactions를 추가해야 합니다. 또한 프로젝트에 이러한 어셈블리에 대한 참조를 추가해야 합니다.

테스트 클래스의 모든 테스트 메서드에 대한 트랜잭션을 만들려면

테스트 클래스의 모든 테스트 메서드에 대한 트랜잭션을 만들려면

  1. 단위 테스트에 대한 Visual Basic 또는 C# 파일을 엽니다.

  2. 다음 Visual C# 코드 예제와 같이 트랜잭션을 TestInitialize에서 만들고 TestCleanup에서 삭제합니다.

    TransactionScope _trans;
    
            [TestInitialize()]
            public void Init()
            {
                _trans = new TransactionScope();
                base.InitializeTest();
            }
    
            [TestCleanup()]
            public void Cleanup()
            {
                base.CleanupTest();
                _trans.Dispose();
            }
    
            [TestMethod()]
            public void TransactedTest()
            {
                DatabaseTestActions testActions = this.DatabaseTestMethod1Data;
                // Execute the pre-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PretestAction != null), "Executing pre-test script...");
                ExecutionResult[] pretestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PretestAction);
                // Execute the test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.TestAction != null), "Executing test script...");
                ExecutionResult[] testResults = TestService.Execute(this.ExecutionContext, this.PrivilegedContext, testActions.TestAction);
                // Execute the post-test script
                // 
                System.Diagnostics.Trace.WriteLineIf((testActions.PosttestAction != null), "Executing post-test script...");
                ExecutionResult[] posttestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PosttestAction);
    
            }
    

DTC 서비스를 시작하려면

이 항목에 소개된 일부 절차에서는 System.Transactions 어셈블리의 형식을 사용합니다. 이러한 절차를 따르기 전에 단위 테스트를 수행하는 컴퓨터에 DTC(Distributed Transaction Coordinator) 서비스가 실행되고 있는지 확인해야 합니다. 그렇지 않으면 테스트가 실패하고 다음과 같은 오류 메시지가 나타납니다. "테스트 메서드 ProjectName.TestName.MethodName에서 예외를 throw했습니다. System.Data.SqlClient.SqlException. 서버 'ComputerName'의 MSDTC를 사용할 수 없습니다."

DTC 서비스를 시작하려면

  1. 제어판을 엽니다.

  2. 제어판에서 관리 도구를 엽니다.

  3. 관리 도구에서 서비스를 엽니다.

  4. 서비스 창에서 Distributed Transaction Controller 서비스를 마우스 오른쪽 단추로 클릭하고 시작을 클릭합니다.

    서비스 상태가 시작됨으로 업데이트됩니다. 이제 System.Transactions를 사용하는 단위 테스트를 실행할 수 있습니다.

중요

DTC(Distributed Transaction Coordinator) 서비스를 시작한 경우에도 System.Transactions.TransactionManagerCommunicationException: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool. ---> System.Runtime.InteropServices.COMException: The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)라는 오류가 나타날 수 있습니다. 이 오류가 나타나는 경우 Distributed Transaction Controller에서 네트워크 액세스를 구성해야 합니다. 자세한 내용은 네트워크 DTC 액세스 사용을 참조하십시오.