[프로젝트] Spring 테스트, DB 오염 막는 법

nemo·2025년 8월 24일
post-thumbnail

▶️ 인사말

안녕하세요!! nemo입니다!! 🐢

요즘 날씨가 진짜 후덥지근하네요
이런 날씨에 프로젝트를 하다 보니 집중력이 조금 떨어지지만… 그래도 꾸준히 나아가고 있습니다
이번 주도 하나씩 경험을 쌓아가면서 개발자로서 한 발 더 나아가는 시간을 보내고 있어요
그럼 오늘도 열심히 달려보겠습니다!!

▶️ 개요

지난번에는 예외 상황을 테스트 코드로 검증하는 방법을 정리했었는데요
이번에는 서비스 테스트에서 repository에 저장된 데이터가 다른 테스트에 영향을 주는 문제를 다뤄보려고 합니다

테스트를 작성하다 보면
첫 번째 테스트에서 저장한 데이터가 그대로 DB에 남아
두 번째 테스트의 결과가 꼬이는
이런 상황을 한 번쯤은 겪게 될텐데
(그게 나야~ 뚜바 뚜밥 뚜비두밥)

테스트는 독립적으로 실행돼야 의미가 있는데 데이터가 섞이면 신뢰성이 깨지죠
그래서 오늘은 Spring Boot 환경에서 이 문제를 어떻게 해결할 수 있는지 정리해보겠습니다

▶️ 해결 방법

🟢 1. @Transactional + 롤백

테스트 메서드마다 트랜잭션을 걸고 실행이 끝나면 자동으로 롤백되는 방식입니다

@SpringBootTest
@Transactional
class AchievementServiceTest {

    @Autowired
    private AchievementRepository achievementRepository;

    @Test
    void saveAchievement() {
        achievementRepository.save(new Achievement("첫 글 작성"));
        assertEquals(1, achievementRepository.count());
    }
}

테스트가 끝나면 롤백 → DB가 깨끗하게 유지됩니다

👉 가장 간단하면서도 많이 쓰이는 방식이에요
단, 정말 DB에 데이터를 남기고 싶다면 @Commit을 붙여야 합니다

🟢 2. @DirtiesContext, 컨텍스트 초기화

테스트 실행 후 Spring 컨텍스트 자체를 리셋하는 방법도 있습니다

@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class AchievementServiceTest { ... }

👉 완전히 새로운 환경에서 테스트할 수 있지만
매번 컨텍스트를 새로 로딩해야 해서 속도가 조금 느려질 수 있습니다

🟢 3. deleteAll(), 수동 초기화

테스트 실행 전후로 직접 데이터를 지워주는 방법입니다

@BeforeEach
void cleanUp() {
    achievementRepository.deleteAll();
}

👉 특정 Repository만 초기화하고 싶을 때는 이 방법이 간단합니다
다만, 코드 중복이 생기기 쉽고 관리가 번거로울 수 있습니다

🟢 4. 테스트 전용 DB 사용 (In-Memory H2 등)

운영 DB와는 별도로 테스트 전용 DB를 두는 방법입니다
보통은 H2 같은 In-Memory DB를 많이 씁니다

application-test.yml

spring:
  datasource:
    url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
    driver-class-name: org.h2.Driver
    username: sa
    password:

👉 @ActiveProfiles("test")를 붙여서 실행하면
운영 DB와 완전히 격리된 환경에서 테스트가 가능해집니다

▶️ 정리

테스트 독립성을 보장하는 방법에는 여러 가지가 있지만

빠르고 간단한 방법은 @Transactional 롤백

완전히 깨끗한 환경이 필요하다면 @DirtiesContext

특정 데이터만 초기화하려면 deleteAll()

운영 DB와 격리하고 싶다면 H2 같은 테스트 전용 DB

이번 프로젝트에서는 deleteAll() 방식을 쓰려고 합니다
가장 많이 쓰이는 방식은 @Transactional이라고 하네요

▶️ 마무리

테스트를 작성하다 보면 "정상 작동"을 확인하는 것도 중요하지만
테스트 간의 독립성을 지키는 게 그만큼이나 중요한 것 같습니다

DB가 오염되면 원인 파악이 힘들어지고 테스트 신뢰성이 크게 떨어진다고 합니다

긴 글 읽어주셔서 감사합니다!! 🐢

참고

https://jiminidaddy.github.io/dev/2021/05/20/dev-spring-%EB%8B%A8%EC%9C%84%ED%85%8C%EC%8A%A4%ED%8A%B8-Repository/

profile
거북이 개발자

0개의 댓글