137 lines
6.8 KiB
Markdown
137 lines
6.8 KiB
Markdown
아래는 **9장. 테스트 피라미드와 실무 적용**에 대한 글입니다. 이 장은 테스트 피라미드라는 이론적 프레임워크를 기반으로 스프링 부트 프로젝트에서 실무적으로 테스트를 적용하는 방법을 다룹니다. 실습 예제와 실무 팁을 포함해 실질적인 가치를 제공하도록 작성했습니다.
|
|
|
|
---
|
|
|
|
## 9장. 테스트 피라미드와 실무 적용
|
|
|
|
테스트는 단순히 코드를 검증하는 도구를 넘어, 프로젝트의 품질과 유지보수성을 높이는 전략입니다. 테스트 피라미드는 이를 체계적으로 설계하는 데 유용한 개념으로, 스프링 부트 프로젝트에서 어떻게 적용할 수 있는지 이 장에서 다룹니다. 실무에서의 전략, 흔한 실수, 그리고 성공적인 테스트 문화를 구축하는 방법까지 살펴보겠습니다.
|
|
|
|
### 9.1 테스트 피라미드 이해
|
|
|
|
테스트 피라미드는 테스트의 종류와 비율을 계층적으로 표현한 모델입니다. 아래에서 위로 갈수록 테스트 범위는 넓어지지만, 수와 실행 비용은 줄어듭니다. 주요 계층은 다음과 같습니다:
|
|
|
|
- **단위 테스트(Unit Tests)**: 가장 아래층으로, 개별 메서드나 클래스를 독립적으로 검증. 빠르고 수가 많음.
|
|
- **통합 테스트(Integration Tests)**: 중간층으로, 여러 모듈이나 계층 간 상호작용을 테스트. 단위 테스트보다 느림.
|
|
- **엔드투엔드 테스트(E2E Tests)**: 최상층으로, 사용자 관점에서 전체 시스템을 검증. 가장 느리고 수가 적음.
|
|
|
|
스프링 부트에서:
|
|
- 단위 테스트: 서비스 로직, 유틸리티 메서드 (예: `UserService.getUserName()`).
|
|
- 통합 테스트: 컨트롤러와 리포지토리 연동 (예: REST API 호출).
|
|
- E2E 테스트: 브라우저나 클라이언트를 통한 전체 워크플로우.
|
|
|
|
피라미드의 핵심은 **단위 테스트를 기반으로 하되, 필요한 만큼 상위 테스트를 보완**하는 것입니다. 단위 테스트가 70-80%, 통합 테스트가 15-25%, E2E 테스트가 5-10% 정도가 일반적인 비율입니다.
|
|
|
|
### 9.2 실무에서의 테스트 전략 수립
|
|
|
|
스프링 부트 프로젝트에서 테스트 전략을 수립하려면 다음 단계를 따릅니다:
|
|
|
|
1. **프로젝트 요구사항 분석**:
|
|
- 빠른 피드백이 중요한가? → 단위 테스트 강화.
|
|
- 외부 시스템 연동이 많나? → 통합 테스트 필요.
|
|
- UI 중심인가? → E2E 테스트 고려.
|
|
|
|
2. **테스트 범위 정의**:
|
|
- 핵심 비즈니스 로직은 단위 테스트로 100% 커버.
|
|
- API 엔드포인트는 통합 테스트로 검증.
|
|
- 주요 사용자 시나리오는 E2E로 확인.
|
|
|
|
3. **도구 선택**:
|
|
- 단위: JUnit, Mockito, AssertJ.
|
|
- 통합: `@SpringBootTest`, Testcontainers.
|
|
- E2E: Selenium, Cypress (웹 애플리케이션용).
|
|
|
|
#### 예제 전략
|
|
간단한 사용자 관리 API 프로젝트:
|
|
- **단위 테스트**: `UserService`의 `createUser()`, `getUserName()` 메서드.
|
|
- **통합 테스트**: `/users` 엔드포인트 호출 및 DB 저장 확인.
|
|
- **E2E 테스트**: 사용자 등록 후 이름 조회 시나리오.
|
|
|
|
```java
|
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
class UserApiIntegrationTest {
|
|
|
|
@Autowired
|
|
private TestRestTemplate restTemplate;
|
|
|
|
@Test
|
|
void createAndGetUser() {
|
|
// 통합 테스트: 사용자 생성
|
|
ResponseEntity<String> createResponse = restTemplate.postForEntity("/users", new User(null, "Alice"), String.class);
|
|
assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);
|
|
|
|
// 통합 테스트: 사용자 조회
|
|
ResponseEntity<String> getResponse = restTemplate.getForEntity("/users/1/name", String.class);
|
|
assertThat(getResponse.getBody()).isEqualTo("Alice");
|
|
}
|
|
}
|
|
```
|
|
|
|
### 9.3 흔한 테스트 실수와 해결 방법
|
|
|
|
실무에서 자주 발생하는 실수와 대처법을 정리했습니다:
|
|
|
|
- **실수 1: 모든 것을 통합 테스트로 작성**
|
|
- 문제: 느리고 유지보수가 어려움.
|
|
- 해결: 단위 테스트로 분리 가능한 로직을 옮기고, 통합 테스트는 핵심 흐름에 집중.
|
|
|
|
- **실수 2: 모킹 과다 사용**
|
|
- 문제: 실제 동작과 달라 신뢰성 하락.
|
|
- 해결: 모킹은 외부 의존성에만 사용하고, 내부 로직은 실제 구현으로 테스트.
|
|
|
|
- **실수 3: 테스트 데이터 관리 부족**
|
|
- 문제: 테스트 간 간섭으로 실패.
|
|
- 해결: `@Transactional` 사용하거나, 각 테스트마다 고유 데이터 생성.
|
|
|
|
- **실수 4: 커버리지에 집착**
|
|
- 문제: 의미 없는 테스트 증가.
|
|
- 해결: 핵심 로직의 품질에 집중하고, 커버리지는 참고 지표로만 활용.
|
|
|
|
#### 예제: 실수 수정
|
|
```java
|
|
// 잘못된 예: 모든 것을 통합 테스트로
|
|
@SpringBootTest
|
|
class BadTest {
|
|
@Test
|
|
void testEverything() {
|
|
// 너무 많은 검증
|
|
}
|
|
}
|
|
|
|
// 개선된 예: 단위 테스트로 분리
|
|
class UserServiceTest {
|
|
@Mock
|
|
private UserRepository repository;
|
|
|
|
@InjectMocks
|
|
private UserService service;
|
|
|
|
@Test
|
|
void getUserName() {
|
|
when(repository.findById(1L)).thenReturn(new User(1L, "Alice"));
|
|
assertThat(service.getUserName(1L)).isEqualTo("Alice");
|
|
}
|
|
}
|
|
```
|
|
|
|
### 9.4 성공적인 테스트 문화 구축
|
|
|
|
테스트를 프로젝트의 핵심 요소로 만들려면 팀 차원의 노력이 필요합니다:
|
|
- **교육과 공유**: 신입 개발자에게 테스트 작성법을 가르치고, 코드 리뷰에서 테스트를 점검.
|
|
- **자동화**: CI/CD에 테스트를 통합해 빠른 피드백 제공 (7장 참고).
|
|
- **책임 분담**: 모든 팀원이 테스트 작성에 참여하도록 장려.
|
|
- **측정과 개선**: 커버리지와 실패율을 모니터링하며 지속적으로 개선.
|
|
|
|
#### 실무 팁
|
|
- **테스트 주도 개발(TDD)**: 요구사항을 테스트로 먼저 작성 후 구현.
|
|
- **페어 프로그래밍**: 테스트 코드를 함께 작성하며 품질 향상.
|
|
- **리팩토링 시간 확보**: 테스트가 없으면 리팩토링이 두려워지므로, 초기에 투자.
|
|
|
|
---
|
|
|
|
### 마무리
|
|
|
|
테스트 피라미드는 스프링 부트 프로젝트에서 테스트를 체계적으로 설계하는 가이드입니다. 단위 테스트로 기반을 다지고, 통합 테스트로 상호작용을 검증하며, E2E 테스트로 사용자 경험을 보장합니다. 실무에서 흔한 실수를 피하고, 팀 전체가 테스트 문화를 받아들이면 안정적이고 확장 가능한 애플리케이션을 만들 수 있습니다. 다음 장에서는 실제 사례를 통해 배운 교훈을 공유하며 이 책을 마무리하겠습니다!
|
|
|
|
---
|
|
|
|
이 글은 테스트 피라미드의 이론과 실무 적용을 균형 있게 다루며, 실습과 팁으로 실질적인 도움을 주고자 했습니다. 추가 요청이나 수정 사항이 있다면 말씀해 주세요! |