Skip to content

리포지토리 쿼리를 실제 PG 컨테이너로 검증하는 테스트 슬라이스 도입 - #197

Merged
i3months merged 1 commit into
devfrom
chore/repository-test-infra
Aug 21, 2026
Merged

리포지토리 쿼리를 실제 PG 컨테이너로 검증하는 테스트 슬라이스 도입#197
i3months merged 1 commit into
devfrom
chore/repository-test-infra

Conversation

@i3months

Copy link
Copy Markdown
Member

#196 을 고치면서 드러난 구조적 공백이다.

기본 테스트 프로파일(application-test.yml)은 DataSource·Hibernate·Flyway 오토컨피그를 명시적으로 제외하고, 모든 @SpringBootTest 가 리포지토리를 @MockitoBean 으로 대체한다. @DataJpaTest 는 의존성에 아예 없었다.

그 결과 코드베이스의 어떤 @Query JPQL 도 자동 검증을 받은 적이 없다. 문법 오류는 물론이고 "삭제된 행을 안 걸렀다" 같은 의미 결함도 CI 를 그대로 통과한다 — #196 의 통계 쿼리 5개가 정확히 그랬고, 로컬에 PG 를 띄워 수동으로 확인해야 했다.

무엇

@PostgresRepositoryTest 를 붙이면 실제 pgvector 컨테이너에서 돈다.

@PostgresRepositoryTest
class SessionFeedbackRepositoryTest {
    @Autowired SessionFeedbackRepository feedbackRepository;
}
결정 이유
이미지 pgvector/pgvector:pg17 infra/postgres/Dockerfile 과 동일. 마이그레이션이 vector 타입·인덱스를 쓴다
스키마는 운영과 같은 Flyway 마이그레이션 H2 로 대체하면 PG 전용 문법(JSONB·vector·NULLS LAST)이 검증 밖으로 빠진다
ddl-auto: validate 유지 엔티티 매핑과 마이그레이션 불일치가 컨텍스트 로딩에서 터진다 — 배포 후에야 알던 사고를 CI 로 당기는 부수 효과
컨테이너는 JVM 당 하나 클래스마다 껐다 켜면 리포지토리 테스트가 늘수록 CI 가 선형으로 느려진다
@DataJpaTest 테스트마다 트랜잭션 롤백 → 데이터 격리

Testcontainers 의존성은 이미 build.gradle 에 선언돼 있었고 한 번도 쓰이지 않았다. 추가한 건 junit-jupiter, spring-boot-testcontainers, spring-boot-data-jpa-test 세 개뿐이다.

첫 사용처

#196 에서 로컬 PG 로 수동 검증했던 케이스를 그대로 옮겼다.

  • statsQueriesExcludeDeletedSessions — 삭제한 세션이 최근 목록·평균 4종에서 빠진다. 필터를 되돌리면 실패하는 것을 확인했다 (Expected size: 1 but was: 2)
  • findSharedByOwnerIncludesDeletedSessions — 반대 방향 계약을 고정한다. 이 쿼리는 탈퇴 시 공유 토큰 회수용이라 삭제된 세션도 포함해야 한다. 여기에 "일관성" 명목으로 필터를 넣으면 탈퇴해도 살아있는 공유 링크가 남는다

지우기 전 상태(2건)도 함께 단언한다 — 필터가 "아무것도 안 거르는" 상태와 구분되도록.

비용

CI 백엔드 잡이 이미지 pull + 컨테이너 기동만큼 길어진다(로컬 기준 첫 실행 약 38초, 이후 캐시). ubuntu-latest 는 Docker 가 이미 있어 워크플로 변경은 없다.

그래서 문서에 "쿼리 동작을 봐야 하는 테스트에만 쓰고, 서비스 로직은 계속 Mockito 단위 테스트로" 라고 명시했다. 기본값은 여전히 컨텍스트 없는 단위 테스트다.

문서

backend/CLAUDE.md §15 갱신 — 테스트 종류 표에 리포지토리 항목 추가, §15.1 에 사용법·제약·운영 PG 버전 올릴 때 컨테이너 태그도 같이 올려야 한다는 점 명시.

기본 테스트 프로파일은 DataSource·Hibernate·Flyway 오토컨피그를 제외하고
모든 리포지토리를 @MockitoBean 으로 대체한다. 그래서 지금까지 코드베이스의
어떤 @query JPQL 도 자동 검증을 받은 적이 없다 — 문법 오류는 물론이고
"삭제된 행을 안 걸렀다" 같은 의미 결함도 CI 를 그대로 통과했다(#196 이 그랬다).

@PostgresRepositoryTest 를 붙이면 실제 pgvector 컨테이너에서 돈다:
- 스키마는 운영과 같은 Flyway 마이그레이션 + ddl-auto=validate
  → 엔티티 매핑과 마이그레이션 불일치도 컨텍스트 로딩에서 잡힌다
- 컨테이너는 JVM 당 하나 (테스트가 늘어도 기동 비용은 한 번)
- @DataJpaTest 라 테스트마다 롤백

첫 사용처로 #196 에서 로컬 PG 로 수동 검증했던 케이스를 그대로 옮겼다.
필터를 되돌리면 실패하는 것을 확인했다(Expected size: 1 but was: 2).
findSharedByOwner 는 삭제 세션을 포함해야 한다는 반대 방향 계약도 함께 고정한다
(탈퇴 시 토큰 회수용이라 여기 필터를 넣으면 살아있는 공유 링크가 남는다).

Testcontainers 의존성은 이미 build.gradle 에 선언돼 있었고 쓰이지 않았다.
junit-jupiter, spring-boot-testcontainers, spring-boot-data-jpa-test 만 추가.
@i3months
i3months merged commit ce203d6 into dev Aug 21, 2026
5 checks passed
@i3months
i3months deleted the chore/repository-test-infra branch August 21, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant