안녕하세요. IT 교육 전문가입니다.
“배치 코드는 어떻게 테스트하나요? 그냥 로컬 DB에 붙여서 돌려보나요?”
많은 주니어 개발자분들이 하는 질문입니다.
실제 운영 DB나 개발 DB에 붙여서 테스트를 하면 데이터가 꼬일 위험이 있고, 무엇보다 느립니다.
빠르고 안전한 개발 사이클(TDD)을 위해서는 인메모리 DB(H2)를 활용한 격리된 테스트 환경이 필수입니다. 오늘은 Spring Batch 테스트 환경을 구축하는 노하우를 공개합니다.
1. 왜 H2 인메모리 DB인가?
- 속도: 디스크 I/O 없이 메모리에서 동작하므로 테스트 속도가 매우 빠릅니다.
- 격리성: 테스트가 끝나면 데이터가 휘발되므로, 매번 깨끗한 상태에서 테스트할 수 있습니다.
- 간편함: 별도의 설치 과정 없이 의존성 추가만으로 사용 가능합니다.
2. 테스트 환경 설정 (application-test.yml)
운영 환경 설정(application.yml)과 분리하여, 테스트만을 위한 설정을 만듭니다. src/test/resources/application-test.yml 파일을 생성합니다.
spring:
datasource:
# 메모리 모드로 동작하며, 테스트 종료 시 DB도 닫힘
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
batch:
jdbc:
initialize-schema: always # 테스트 시작 시 배치 메타 테이블 생성
job:
enabled: false # 중요! 테스트 실행 시 자동으로 Job이 도는 것을 방지
jpa:
hibernate:
ddl-auto: create-drop # 테스트 시작 시 테이블 생성, 종료 시 삭제
show-sql: true
핵심:
spring.batch.job.enabled: false로 설정해야 합니다. 그렇지 않으면 테스트 컨텍스트가 로드될 때 모든 Job이 자동으로 실행되어 테스트를 방해할 수 있습니다.
3. 테스트 유틸리티 클래스 작성 (BatchTestSupport)
Spring Batch 테스트에는 많은 보일러플레이트 코드가 필요합니다. 이를 줄이기 위해 부모 클래스를 만들어 상속받아 쓰는 것이 효율적입니다.
@SpringBootTest
@SpringBatchTest // Batch 테스트를 위한 유틸리티 빈(JobLauncherTestUtils 등) 자동 등록
@ActiveProfiles("test") // application-test.yml 적용
public abstract class BatchTestSupport {
@Autowired
protected JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
protected JobRepositoryTestUtils jobRepositoryTestUtils;
@AfterEach
void tearDown() {
// 각 테스트가 끝날 때마다 메타 데이터 삭제 (데이터 오염 방지)
jobRepositoryTestUtils.removeJobExecutions();
}
}
4. 실제 Job 테스트 코드 작성
이제 위에서 만든 BatchTestSupport를 상속받아 실제 HelloJob을 테스트해 봅시다.
class HelloJobConfigTest extends BatchTestSupport {
@Autowired
private Job helloJob; // 테스트할 Job 주입
@Test
@DisplayName("HelloJob이 정상적으로 실행되고 상태가 COMPLETED여야 한다")
void simpleJobTest() throws Exception {
// given
// 필요한 경우 테스트 데이터 사전 insert (DB)
jobLauncherTestUtils.setJob(helloJob); // 테스트 대상 Job 설정
// when
// Job 실행
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
// then
// 1. 상태 검증
assertThat(jobExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
assertThat(jobExecution.getExitStatus()).isEqualTo(ExitStatus.COMPLETED);
// 2. Step 실행 횟수 등 상세 검증 (Optional)
// assertThat(jobExecution.getStepExecutions().size()).isEqualTo(1);
}
}
코드 분석
@SpringBatchTest: Spring Batch 팀에서 제공하는 강력한 테스트 어노테이션입니다.JobLauncherTestUtils를 자동으로 빈으로 등록해 줍니다.launchJob(): Job을 실제로 실행시키고 그 결과(JobExecution)를 반환합니다.- 검증: AssertJ를 사용하여 Job의 최종 상태가
COMPLETED인지 확인합니다.
5. 결론
이렇게 구성된 테스트 환경은 로컬 DB가 꺼져 있어도 돌아가고, 네트워크가 끊겨도 돌아갑니다. 무엇보다 CI/CD 파이프라인에서 자동으로 돌며 코드의 품질을 지켜주는 든든한 파수꾼이 됩니다.
“테스트 코드가 없는 배치는 시한폭탄과 같다”는 말을 명심하세요. H2와 함께 안전한 배치 개발 하시기 바랍니다.





