단위 테스트 (Unit Test)
단위 테스트는 소프트웨어의 가장 작은 단위인 개별 모듈이나 컴포넌트를 독립적으로 테스트하는 과정이다.
이는 마치 자동차를 조립하기 전에 각 부품이 제대로 작동하는지 확인하는 것과 비슷하다.
특징과 목적
단위 테스트의 주요 특징과 목적은 다음과 같다:
- 독립성: 각 테스트는 다른 테스트와 독립적으로 실행된다.
- 자동화: 테스트를 자동으로 실행할 수 있어 빠르고 반복적인 테스트가 가능하다.
- 빠른 피드백: 개발자가 코드를 변경할 때마다 즉시 테스트를 실행하여 문제를 빠르게 발견할 수 있다.
- 버그 조기 발견: 개발 초기 단계에서 버그를 찾아 수정 비용을 줄일 수 있다.
테스트 범위
단위 테스트는 주로 다음과 같은 요소를 검증한다다:
- 개별 함수나 메서드의 동작
- 클래스의 메서드 간 상호작용
- 특정 모듈이나 컴포넌트의 기능
수행 시점
단위 테스트는 개발 과정 중 가장 먼저 수행되는 테스트이다.
일반적으로 개발자가 코드를 작성하면서 동시에 또는 바로 후에 테스트를 작성하고 실행한다.
계산기 프로그램의 단위 테스트:
|
|
검증 대상
단위 테스트의 주요 검증 대상은 다음과 같다:
- 함수나 메서드의 반환 값
- 객체의 상태 변화
- 예외 처리의 정확성
단위 테스트의 종류
상태 기반 테스트: 메서드 실행 후 객체의 상태를 확인한다.
동작 기반 테스트: 메서드 호출 시 다른 객체와의 상호작용을 확인한다. 보통 mock 객체를 사용한다.
진행 방식
단위 테스트는 보통 다음과 같은 단계로 진행된다:
테스트 케이스 설계: 검증하고자 하는 동작을 정의한다.
테스트 코드 작성: 주로 AAA (Arrange-Act-Assert) 패턴을 사용한다.
|
|
- 테스트 실행: 자동화된 도구를 사용하여 테스트를 실행한다.
- 결과 분석: 테스트 결과를 확인하고 필요한 경우 코드를 수정한다.
단위 테스트의 일반적인 구조
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# AAA (Arrange-Act-Assert) 패턴 def test_user_registration(): # Arrange (준비): 테스트에 필요한 객체와 데이터 설정 user_service = UserService() user_data = { "username": "testuser", "email": "test@example.com", "password": "secure123" } # Act (실행): 테스트하려는 기능 실행 result = user_service.register_user(user_data) # Assert (검증): 결과 확인 assert result.success == True assert result.user.username == "testuser" assert result.user.email == "test@example.com"
예시
간단한 계산기 프로그램의 덧셈 기능에 대한 단위 테스트를 예로 들어보자:
이 예시에서 우리는 Calculator 클래스의 add 메서드를 테스트한다.
테스트 함수는 2와 3을 더했을 때 5가 나오는지 확인한다.
이런 식으로 다양한 입력값에 대해 테스트를 작성하여 add 메서드가 정확히 동작하는지 검증할 수 있다.
단위 테스트를 통해 개발자는 자신의 코드가 의도대로 동작하는지 빠르게 확인할 수 있으며, 이는 전체 소프트웨어의 품질을 향상시키는 데 큰 도움이 된다.
소프트웨어의 가장 작은 테스트 가능한 단위(보통 함수나 메서드)를 독립적으로 검증하는 테스트 방법.
이는 코드의 각 부분이 의도한 대로 정확히 작동하는지 확인하는 것을 목적으로 한다.
단위 테스트의 중요한 원칙
테스트 구조화
- 각 테스트는 하나의 동작만 검증한다
- 테스트 설정(Setup), 실행(Action), 검증(Assert) 단계가 명확히 구분된다
- 테스트 간 의존성이 없도록 설계한다.
테스트 케이스 설계
- 정상 케이스뿐만 아니라 예외 상황도 테스트한다.
- 정상 케이스: 예상되는 일반적인 입력
- 경계 케이스: 최대값, 최소값, 0 등
- 예외 케이스: 잘못된 입력, 에러 상황
- 경계값과 특수한 조건들을 고려한다.
- 모든 코드 경로를 커버하도록 테스트 케이스를 작성한다.
- 정상 케이스뿐만 아니라 예외 상황도 테스트한다.
코드 품질
- 테스트 코드도 실제 코드만큼 깨끗하게 작성되어야 한다.
- 테스트의 의도가 명확히 드러나도록 작성한다.
- 중복을 최소화하고 재사용 가능한 설정을 활용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 테스트 헬퍼 함수를 활용한 코드 중복 제거 def create_test_user(self, role="user"): return User( username=f"test_{role}", email=f"{role}@example.com", role=role ) def test_admin_permissions(self): admin = self.create_test_user(role="admin") assert admin.can_delete_users() == True def test_user_permissions(self): user = self.create_test_user(role="user") assert user.can_delete_users() == False