테스트 전략 설계 및 구현
성공적으로 빌드되는 SQL 데이터베이스 프로젝트가 내부 저장 프로시저가 올바른 결과를 반환한다는 의미는 아닙니다. 프로시저는 오류 없이 컴파일할 수 있으며 잘못된 합계를 계산하거나 유효성 검사를 건너뛸 수 있습니다. 테스트는 프로덕션에 도달하기 전에 이러한 문제를 해결합니다.
데이터베이스 테스트 수준 이해
데이터베이스 테스트는 각기 다른 문제 유형을 포착하는 여러 계층에서 작용합니다.
-
빌드 유효성 검사는 이미 있는 단계입니다
dotnet build. 구문 오류와 깨진 개체 참조를 탐지합니다. 빠르지만 스키마가 구조적으로 유효하다는 것을 증명할 뿐입니다. - 단위 테스트는 개별 저장 프로시저 및 함수가 지정된 입력 집합에 적합한 결과를 생성하는지 확인합니다. 논리 오류를 잡아냅니다.
- 통합 테스트는 배포된 데이터베이스에 대해 엔드투엔드 시나리오를 실행합니다. 개체가 올바르게 함께 작동한다는 것을 증명하지만 실행 중인 인스턴스가 필요하며 가장 많은 시간이 소요됩니다.
각 레이어는 이전 계층보다 느리고 비용이 많이 들지만 이전 계층에서 수행할 수 없는 문제도 포착합니다.
SQL Server 단위 테스트 만들기
Visual Studio의 SSDT(SQL Server Data Tools)에는 데이터베이스 단위 테스트를 위한 기본 제공 프레임워크가 포함되어 있습니다. 각 테스트는 라이브 데이터베이스에 대해 T-SQL을 실행하고 테스트 조건을 사용하여 결과의 유효성을 검사합니다.
단위 테스트의 구조
각 테스트에는 setup-execute-cleanup 패턴을 따르는 세 개의 섹션이 있습니다.
- 사전 테스트: 테스트에 필요한 데이터를 설정합니다. 고객 레코드를 삽입하고 이전 실행에서 남은 데이터를 지웁 수 있습니다.
- 테스트: 테스트 중인 작업을 실행합니다. 저장 프로시저를 호출하고 뷰를 쿼리합니다.
- 테스트 후: 다음 실행을 오염하지 않도록 테스트 후 정리합니다.
테스트 조건
테스트 T-SQL이 실행된 후 테스트 조건은 다시 돌아온 내용의 유효성을 검사합니다. 가장 일반적으로 사용되는 조건은 다음과 같습니다.
- 행 수: 결과 집합에 예상 행 수가 포함되어 있음을 확인합니다.
- 스칼라 값: 결과 집합의 특정 셀에 예상 값이 포함되어 있음을 확인합니다.
- 예상 스키마: 결과 집합에 예상 열 이름 및 데이터 형식이 있는지 확인합니다.
다른 기본 제공 조건에는 데이터 체크섬, 빈 결과 집합, 비어 있지 않은 결과 집합 및 실행 시간이 포함됩니다.
단위 테스트 프로젝트 만들기
Visual Studio에서 SQL Server 단위 테스트를 설정하려면 몇 가지 단계를 수행합니다.
- SQL 데이터베이스 프로젝트를 엽니다.
- SQL Server 개체 탐색기에서 테스트하려는 저장 프로시저 또는 함수를 찾습니다.
- 개체를 마우스 오른쪽 단추로 클릭하고 단위 테스트 만들기를 선택합니다.
- C# 테스트 프로젝트를 선택하거나 만듭니다.
- 개발 데이터베이스에 대한 테스트 연결을 설정합니다.
- 단위 테스트를 실행하기 전에 데이터베이스 프로젝트 자동 배포를 선택합니다. 이 옵션은 테스트 데이터베이스를 최신 프로젝트 변경 내용과 동기화된 상태로 유지합니다.
테스트 논리를 작성하고 테스트 조건을 연결하는 T-SQL 템플릿을 사용하여 디자이너가 열립니다.
효과적인 데이터베이스 단위 테스트 작성
좋은 단위 테스트는 특정 질문에 대답합니다. "이 절차는 알려진 입력에 대해 수행해야 하는 작업을 수행하나요?" 다음은 주문이 고객의 연간 총액을 올바르게 업데이트하도록 테스트 uspPlaceNewOrder하는 예제입니다.
-- Pre-test: Set up customer and clear previous data
DECLARE @CustomerID INT;
INSERT INTO [Sales].[Customer] (CustomerName) VALUES (N'Test Customer');
SET @CustomerID = SCOPE_IDENTITY();
DELETE FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID;
-- Test: Place an order and verify YTDOrders updated correctly
DECLARE @RC INT;
EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, GETDATE(), 'O';
SELECT [YTDOrders]
FROM [Sales].[Customer]
WHERE [CustomerID] = @CustomerID;
📝 이 테스트 T-SQL을 스칼라 값 테스트 조건과 페어링합니다. 이 조건은 YTDOrders 값을 100으로 예상합니다.
부정 테스트
또한 잘못된 입력을 받을 때 저장 프로시저가 올바르게 실패하는지 확인해야 합니다. 예컨대 이미 발송 처리된 주문을 취소하려 할 때는 반드시 오류를 표시해야 하며, 아무런 알림 없이 성공 처리되어서는 안 됩니다. 부정 테스트는 예상된 오류가 발생했음을 확인합니다.
이전 섹션의 3단계에서 단위 테스트 만들기 를 선택하면 Visual Studio는 선택한 각 저장 프로시저에 대한 테스트가 포함된 파일을 사용하여 솔루션 탐색기.cs 에서 C# 테스트 프로젝트를 생성합니다. 예를 들어 테스트를 uspCancelOrder만든 경우 생성된 파일에는 이름이 지정된 Sales_uspCancelOrder_Test섹션이 포함됩니다. 해당 테스트를 부정 테스트로 표시하려면 .cs에서 파일을 열고 바로 위에 특성을 추가하고 ExpectedSqlException 파일을 저장합니다.
[TestMethod()]
[ExpectedSqlException(Severity = 16, MatchFirstError = false, State = 1)]
public void Sales_uspCancelOrder_FilledOrder_Test()
이 테스트는 저장 프로시저가 지정된 심각도 및 상태와 일치하는 오류를 발생시키는 경우에만 통과합니다. 프로시저가 자동으로 성공하면 테스트가 실패합니다. 이것이 바로 원하는 것입니다.
통합 테스트 접근 방식 설계
단위 테스트는 개별 개체를 격리합니다. 통합 테스트는 더 나아가 여러 작업에 걸쳐 있는 시나리오를 테스트합니다. 다음과 같은 질문에 대답합니다.
- 저장 프로시저 호출 시퀀스가 데이터베이스를 예상 상태로 유지하나요?
- 애플리케이션 계층을 통해 데이터가 도착하면 트리거가 올바르게 실행되나요?
- 일련의 관련 테이블이 변경된 후 뷰가 정확한 결과를 반환합니까?
통합 테스트에는 전용 데이터베이스가 필요합니다. 단위 테스트가 실행되기 전에 데이터베이스 프로젝트를 자동으로 배포하여 각 프로젝트를 실행 하기 전에 테스트 인스턴스에 SQL 데이터베이스 프로젝트를 배포합니다 . 이 설정은 테스트 스키마를 최신 상태로 유지합니다.
테스트 데이터베이스에 대한 고려 사항
단위 테스트와 통합 테스트는 모두 라이브 데이터베이스에 대해 T-SQL을 실행하므로 테스트 환경에서는 신뢰할 수 있는 결과를 생성하기 위해 신중한 설정이 필요합니다.
- 프로덕션에서 테스트를 격리합니다. 별도의 인스턴스 또는 전용 테스트 데이터베이스를 사용합니다. 프로덕션에 대한 테스트를 실행하는 것은 권장되지 않습니다.
- 각 실행 전에 알려진 상태로 다시 설정합니다. 배포 후 스크립트 또는 테스트 정리 스크립트는 이 문제를 처리합니다.
- 로컬 개발 및 CI 파이프라인이 각각 코드 변경 없이 올바른 데이터베이스를 가리키도록 구성 파일에서 연결 문자열을 외부화합니다.
CI/CD 파이프라인에 테스트 통합
빌드 및 배포 후 테스트 단계를 추가하여 모든 커밋에서 테스트가 자동으로 실행됩니다. Azure DevOps에서 다음 작업을 사용합니다 VSTest .
- task: VSTest@2
inputs:
testAssembly: '**\*Tests.dll'
searchFolder: '$(System.DefaultWorkingDirectory)'
GitHub Actions에서 다음을 사용하여 dotnet test테스트를 실행합니다.
- name: Run database unit tests
run: dotnet test ./DatabaseTests/DatabaseTests.csproj
팁 (조언)
테스트를 실행하기 전에 데이터베이스 프로젝트를 자동으로 배포하도록 테스트 프로젝트를 구성합니다. 이 설정은 테스트 데이터베이스 스키마가 테스트 시 프로젝트와 일치하도록 합니다.
테스트가 실패하면 파이프라인이 중지되고 변경 내용이 스테이징 또는 프로덕션에 도달하지 않습니다. 이 지연은 팀이 환경에 영향을 미치기 전에 문제를 해결할 수 있는 시간을 제공합니다.
주요 내용
데이터베이스 테스트는 구조적 정확성에 대한 빌드 유효성 검사, 논리 확인을 위한 단위 테스트 및 엔드 투 엔드 워크플로에 대한 통합 테스트의 세 가지 수준에 걸쳐 있습니다. SQL Server 단위 테스트는 테스트 사전 작업, 테스트 작업 및 테스트 사후 작업의 3단계 구조를 따릅니다. 저장 프로시저 및 함수 동작을 확인하려면 , Scalar Value및 Row Count. 같은 Expected Schema테스트 조건을 사용합니다. 오류 처리 경로의 유효성을 검사해야 하는 메서드를 테스트하려면 특성을 추가 ExpectedSqlException 합니다. CI/CD 파이프라인에 테스트 프로젝트를 연결하여 실패한 테스트는 변경 내용이 스테이징 또는 프로덕션에 도달하기 전에 배포를 차단합니다. 이러한 세 계층은 팀이 불안 대신 자신 있게 데이터베이스 변경 내용을 배포할 수 있는 안전망을 형성합니다.