-
Notifications
You must be signed in to change notification settings - Fork 8
test: flyway 스크립트를 검증하는 테스트 코드 작성 #588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: flyway 스크립트를 검증하는 테스트 코드 작성 #588
Conversation
Walkthrough
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
15-18: 테스트 메서드 본문이 비어있는 이유를 명확히 해주세요.빈 메서드 본문이 의도적인 것이지만, 컨텍스트 로딩만으로 검증이 완료된다는 점을 주석으로 설명하면 코드 가독성이 향상됩니다.
🔎 제안하는 개선안
@Test void flyway_스크립트가_정상적으로_수행되는지_확인한다() { - + // Flyway 마이그레이션은 Spring 컨텍스트 초기화 시점에 자동으로 실행됩니다. + // 스크립트에 구문 오류나 JPA 엔티티와의 불일치가 있으면 컨텍스트 로딩이 실패합니다. }또한, Flyway가 실제로 실행되었는지 명시적으로 확인하려면 다음과 같이 개선할 수 있습니다:
+import org.flywaydb.core.Flyway; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + @TestContainerDataJpaTest @TestPropertySource(properties = { "spring.flyway.enabled=true", "spring.flyway.baseline-on-migrate=true", "spring.jpa.hibernate.ddl-auto=validate" }) class FlywayMigrationTest { + @Autowired + private Flyway flyway; + @Test void flyway_스크립트가_정상적으로_수행되는지_확인한다() { - + // Flyway 마이그레이션이 성공적으로 적용되었는지 확인 + assertThat(flyway.info().applied()).isNotEmpty(); } }
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
7-12: 테스트 접근 방식이 효과적합니다!컨텍스트 초기화 시점에 Flyway 스크립트 검증을 수행하는 방식은 타당합니다. 설정된 속성들도 적절하며,
@TestContainerDataJpaTest어노테이션을 통해 실제 MySQL 8.0 TestContainer를 사용하므로 다음 점들이 보장됩니다:
- 실제 MySQL 데이터베이스에 대한 마이그레이션 검증 - H2 호환성 문제 없음
- AUTO_INCREMENT, ENGINE=InnoDB, 백틱(`) 등 MySQL 전용 구문이 정상 작동
- 개발/프로덕션 환경과 동일한 데이터베이스에서 테스트되므로 신뢰도 높음
테스트는 현재 올바르게 구현되어 있습니다.
f11d220 to
9bd83cc
Compare
9bd83cc to
7d8c1a9
Compare
- 새로운 MySQL 환경에서 마이그레이션이 이루어지도록 수정
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
19-22: 테스트 메서드에 명시적인 검증 또는 주석을 추가하는 것을 권장합니다.현재 구현은 컨텍스트 로딩 중 Flyway 마이그레이션이 실행되고, 스크립트에 문제가 있으면 테스트가 실패하는 방식으로 동작합니다. 이는 유효한 접근 방식이지만, 다음과 같은 개선이 가능합니다:
- 명시적인 검증 추가: Flyway의
MigrationInfo를 조회하여 마이그레이션 성공 여부를 명시적으로 확인- 의도 문서화: 주석으로 테스트의 동작 방식을 설명
🔎 명시적인 검증을 추가하는 방법
+import org.flywaydb.core.Flyway; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + @TestContainerSpringBootTest @TestPropertySource(properties = { "spring.flyway.enabled=true", - "spring.flyway.baseline-on-migrate=true", "spring.jpa.hibernate.ddl-auto=validate" }) -@DirtiesContext(classMode = BEFORE_CLASS) class FlywayMigrationTest { + @Autowired + private Flyway flyway; + @Test void flyway_스크립트가_정상적으로_수행되는지_확인한다() { - + // given & when: Spring 컨텍스트 로딩 시 Flyway 마이그레이션 자동 실행 + + // then: 모든 마이그레이션이 성공적으로 적용되었는지 확인 + var info = flyway.info(); + assertThat(info.pending()).isEmpty(); + assertThat(info.current()).isNotNull(); } }또는 주석만 추가하는 방법:
@Test void flyway_스크립트가_정상적으로_수행되는지_확인한다() { - + // 이 테스트는 Spring 컨텍스트 로딩 시 Flyway 마이그레이션이 성공적으로 수행되는지 검증합니다. + // 마이그레이션 스크립트에 문법 오류나 스키마 불일치가 있으면 컨텍스트 로딩이 실패하여 테스트가 실패합니다. }
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
18-22: 이전 리뷰에서 지적된 사항:baseline-on-migrate속성 제거 권장TestContainers는 항상 깨끗한 데이터베이스로 시작하므로
spring.flyway.baseline-on-migrate=true설정은 불필요합니다. 이 설정은 기존 스키마에 Flyway를 처음 적용할 때 사용하는 것으로, 테스트 환경에서는 필요하지 않습니다.
🧹 Nitpick comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
42-44: 빈 테스트 메서드가 유효하지만, 명시적인 검증 추가를 고려해보세요현재 구현은 컨텍스트 로딩 실패를 통해 마이그레이션 오류를 감지하는 방식으로, 다음과 같은 검증이 암묵적으로 이루어집니다:
- Flyway 마이그레이션 실행: SQL 문법 오류가 있으면 실패
- JPA 스키마 검증:
ddl-auto=validate설정으로 엔티티와 스키마 불일치 감지- 컨텍스트 초기화: 모든 빈이 정상적으로 생성되는지 확인
다만, 다음과 같은 선택적 개선을 고려해볼 수 있습니다:
🔎 명시적인 검증 로직 예시
+import org.flywaydb.core.Flyway; +import org.springframework.beans.factory.annotation.Autowired; +import static org.assertj.core.api.Assertions.assertThat; + @Test void flyway_스크립트가_정상적으로_수행되는지_확인한다() { + // Flyway 마이그레이션이 실제로 실행되었는지 확인 + assertThat(flyway.info().applied()).isNotEmpty(); + + // 또는 로그를 통해 마이그레이션 실행 여부 확인 + // 예: flyway_schema_history 테이블 조회 등 }이렇게 하면 테스트 의도가 더 명확해지고, 실패 시 원인 파악이 쉬워집니다.
현재 구조도 PR 목표(스크립트 검증 및 오류 감지)를 충분히 달성하므로, 이는 선택적인 개선 사항입니다.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
src/test/java/com/example/solidconnection/support/RedisTestContainer.java (1)
RedisTestContainer(8-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
25-40: 컨테이너 설정과 초기화 로직이 올바르게 구현되었습니다다음과 같이 잘 구성되어 있습니다:
MySQLContainer 설정 (라인 26-29)
@Container애노테이션과 static final로 선언하여 생명주기가 올바르게 관리됩니다- 테스트용 데이터베이스 이름, 사용자명, 비밀번호가 명확하게 지정되어 있습니다
FlywayMySQLInitializer 구현 (라인 31-40)
ApplicationContextInitializer인터페이스를 올바르게 구현했습니다- 컨테이너의 JDBC URL과 인증 정보를 Spring 환경에 주입하는 로직이 정확합니다
RedisTestContainer와 동일한 패턴을 따라 일관성이 있습니다
Gyuhyeok99
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다~
| void flyway_스크립트가_정상적으로_수행되는지_확인한다() { | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Spring Boot 컨텍스트가 정상적으로 시작되면
// Flyway 마이그레이션과 ddl-auto=validate 검증이 성공한 것
이런느낌의 주석만 안에 하나 들어가는 거 어떤가요~?
Hexeong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM :) 다른 분들 리뷰 진행해주시면 될 것 같습니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
18-22:spring.flyway.baseline-on-migrate=true설정 재검토가 필요합니다.이전 리뷰에서 이미 지적되었듯이, TestContainers는 항상 깨끗한 데이터베이스로 시작하므로
baseline-on-migrate설정은 불필요합니다. 이 설정은 기존 스키마에 flyway_schema_history 테이블이 없을 때 사용하는 옵션입니다.테스트 환경에서는 제거하는 것을 권장합니다.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
src/test/java/com/example/solidconnection/support/RedisTestContainer.java (1)
RedisTestContainer(8-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (2)
31-40: Initializer 구현이 적절합니다.
RedisTestContainer와 동일한 패턴으로 구현되어 일관성이 있습니다. MySQL 컨테이너 시작 타이밍 문제만 해결되면 정상적으로 동작할 것입니다.
42-46: 테스트 방식이 적절합니다.컨텍스트 로딩만으로 Flyway 마이그레이션과 JPA 스키마 검증을 수행하는 방식은 간결하면서도 효과적입니다.
- 실제로 39개의 마이그레이션 스크립트(V1~V39)가
src/main/resources/db/migration/디렉토리에 존재하며@TestPropertySource에서spring.flyway.enabled=true와spring.jpa.hibernate.ddl-auto=validate를 설정하고MySQLContainer를 통해 테스트용 DB를 구성하므로Spring Boot가 시작될 때 자동으로 Flyway 마이그레이션이 실행되고, 이어서 Hibernate의 스키마 검증이 진행됩니다. 불일치가 발생하면 컨텍스트 로딩 단계에서 실패하므로 테스트 신뢰성도 충분합니다. 주석도 의도를 명확하게 설명하고 있습니다.
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java
Outdated
Show resolved
Hide resolved
- 또한 MySQLTestContainer 코드와 유사한 컨벤션을 가지도록 수정
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
15-19: 이전 리뷰에서 지적된baseline-on-migrate설정이 여전히 남아있습니다.TestContainers는 항상 깨끗한 데이터베이스로 시작하기 때문에
spring.flyway.baseline-on-migrate=true설정이 불필요합니다. 이 설정은 기존 스키마는 있지만flyway_schema_history테이블이 없는 데이터베이스를 처리하기 위한 것으로, 테스트 환경에서는 해당되지 않습니다.제거를 권장합니다:
@TestPropertySource(properties = { "spring.flyway.enabled=true", - "spring.flyway.baseline-on-migrate=true", "spring.jpa.hibernate.ddl-auto=validate" })
🧹 Nitpick comments (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
22-29: 컨테이너 시작 타이밍 문제가 잘 해결되었습니다!이전 리뷰에서 지적되었던 컨테이너 시작 타이밍 이슈가 static 블록을 통해 완벽하게 해결되었습니다. 다음과 같은 개선점이 보입니다:
- 타이밍 보장: static 블록에서 컨테이너를 시작하여
FlywayMySQLInitializer가 실행되기 전에 컨테이너가 준비됩니다.- 일관된 패턴:
RedisTestContainer와 동일한 구조를 따라 코드베이스의 일관성이 향상되었습니다.- 네이밍 통일:
MYSQL에서CONTAINER로 변수명을 변경하여RedisTestContainer와 컨벤션이 일치합니다.선택적 개선: 명시적 shutdown hook 추가
TestContainers가 자동으로 정리하지만,
RedisTestContainer와 완전히 동일한 패턴을 원한다면 명시적 shutdown hook을 추가할 수 있습니다:static { CONTAINER.start(); + Runtime.getRuntime().addShutdownHook(new Thread(CONTAINER::stop)); }단, 이는 선택 사항이며 현재 구현도 충분히 안전합니다.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (1)
src/test/java/com/example/solidconnection/support/RedisTestContainer.java (1)
RedisTestContainer(8-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
src/test/java/com/example/solidconnection/database/FlywayMigrationTest.java (2)
31-40: Initializer 구현이 깔끔합니다!
FlywayMySQLInitializer가 다음과 같이 잘 구현되었습니다:
- 표준 패턴 준수:
ApplicationContextInitializer를 구현하여 컨테이너 설정을 Spring 컨텍스트에 주입하는 표준 방식을 따릅니다.- 완전한 설정 주입: datasource의 URL, username, password를 모두 적절히 주입합니다.
- 코드베이스 일관성:
RedisTestContainer와 동일한 구조로 작성되어 유지보수가 용이합니다.
42-46: 테스트 설계가 탁월하고 주석이 잘 추가되었습니다!이 테스트는 다음과 같이 우아하게 설계되었습니다:
암묵적 검증: 메서드 본문이 비어있지만, Spring Boot 컨텍스트 로딩 과정에서 다음을 자동으로 검증합니다:
- Flyway 마이그레이션 스크립트의 파일명, 버전, SQL 문법
- JPA 엔티티와 DB 스키마 간의 정합성 (
ddl-auto=validate)명확한 의도 전달: 추가된 주석이 "컨텍스트 로딩 = 검증 성공"이라는 설계 의도를 명확히 설명합니다.
피드백 반영: 이전 리뷰에서 Gyuhyeok99님이 제안한 주석이 잘 반영되었습니다.
이러한 방식은 Flyway 검증 테스트의 모범 사례로, 별도의 assertion 없이도 스크립트 문제를 빌드 시점에 포착할 수 있습니다.
관련 이슈
작업 내용
flyway는
dev,prod프로파일에만 사용하고 있고,ddl-auto: validate로 스크립트와 JPA 간 명세 불일치를 감지합니다. 기존에는local환경에서 스크립트를 작성하고 이에 대한 검증을 수행하기 위해서application-db.yml의local프로파일을 수정해야 했습니다.스크립트의 버전 충돌이 발생하거나 파일명 형식이 일치하지 않으면 스크립트가 실행되지 않거나, 런타임 에러가 발생하게 됩니다.
따라서 빌드 시점에 스크립트 검증을 수행하도록 gradle
flyway플러그인과 H2 데이터베이스를 사용하였습니다.그러나 스크립트 가 잘못 작성되어, 런타임 에러가 발생하여 서버가 다운되는 상황이 있었습니다.
이에 관련 테스트 클래스를 생성하였고,
@TestPropertySource를 사용하여 flyway 설정을 사용하도록 구현했습니다.특이 사항
실제 동작입니다. 문법 오류를 잘 감지합니다.
이제 애플리케이션 빌드하면 스크립트 파일명 관련 검증이 가능하며, 테스트 코드를 실행하면 스크립트 SQL문 관련 검증이 가능합니다. 이제 스크립트로 인해 고통(?)받는 일은 없으면 좋겠네요 ..!
리뷰 요구사항 (선택)
로컬에서는 테스트 통과했는데 ... 깃허브 액션에서는 실패했습니다. 테스트 순서에 영향을 받나 싶어 컨텍스트를 날리고 수행하도록 했지만 실패해서, 별도의 MySQL 컨테이너를 만들어 수행하는 방법으로 구현했습니다.
현재로서는 지금 방법이 간단한 거 같긴 합니다. 더 좋은 방법이 있다면 말씀해주세요 !