스프링

스프링부트 테스트시의 testcontainer 사용법 및 후기

rkrkrr0101 2024. 2. 12. 02:27

사용법은

먼저 의존성 추가후

testImplementation 'org.testcontainers:testcontainers:1.19.4' // TC 의존성
testImplementation 'org.testcontainers:junit-jupiter:1.19.4'  // TC 의존성
testImplementation 'org.testcontainers:mysql:1.19.4'     // mySQL 컨테이너 사용
testImplementation 'org.testcontainers:jdbc:1.19.4'           // DB와의 JDBC connection

해당 테스트할곳에

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
//@Sql(scripts = ["classpath:/init_data/fulltext_index_create.sql"])
class PostRepositoryTest(@Autowired val postRepository: PostRepository,
                         @Autowired val memberRepository: MemberRepository,
    @Autowired val dataSource:DataSource ) {
    companion object{
        @JvmStatic
        @Container
        val mysqlContainer=MySQLContainer("mysql:8.0.33")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("1234")
            .withEnv("MYSQL_TCP_PORT","3307")
    }

이렇게 

@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers

를 추가하고(AutoConfigureTestDatabase는 datajpatest가 기본적으로 메인의 application.properties를 바라보는걸 끊어서 테스트쪽 설정을 보게만들어줌)

    companion object{
        @JvmStatic
        @Container
        val mysqlContainer=MySQLContainer("mysql:8.0.33")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("1234")
            .withEnv("MYSQL_TCP_PORT","3307")
            .withInitScript("스크립트경로")//넣을 스크립트있으면 넣으면됨
    }

이렇게 컨테이너를 띄워주고나서

테스트 설정파일에서

spring:
  datasource:
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
    url: jdbc:tc:mysql:8.0.36:///testdb
    username: test
    password: 1234

이부분만 수정해주면됨,즉 url과(여기서 jdbc:tc: 인거 주의)드라이버 설정만 하면됨

 

그리고 테스트코드에서는 따로 뭐 안해주고 하던대로 하면됨

 

후기

이걸 사용한 이유가,mysql의 full text search를 테스트할 방법을 찾아야해서 사용했음(h2에서는 지원안하니)

근데 일단 뜨는데 걸리는속도가 너무 느리고,

 

jpa의 ddl을 사용하기가 매우 까다로워졌는데(그래서 보통 ddl-auto를 끄고쓰는듯),

그 이유는 테스트컨테이너가 뜬다음에 테스트컨테이너의 init 스프링이 실행되고 ddl을 하는 순서상,ddl create를 해버리면 그냥 다버리고 다시만드니까 의미가없고,update도 마찬가지임

그렇다고 자동ddl버리고 테스트컨테이너의 스크립트실행을 사용하면,ddl 엔티티의 변경점이 생기면 일일이 다 수정해줘야함  

근데 fulltext인덱스를 추가해야하는 전문검색특성상,jpa에선 지원안하니까 jdbc연결해서 쌩쿼리를 날리는방법밖에 없어서 매우지저분해졌음

1.jpa ddl사용+jdbc로 쌩쿼리

2.jpa ddl끄고 테스트컨테이너 initscript사용,단 엔티티변경점이 생기면 다 알아서 수정

승부존에 걸림

 

결론

일단 젤문제는 뜨는데 속도가 너무느려져서,걍 버리고 모킹해서 테스트를 할까 생각중임

런던파 싫어하는사람이 많은거같긴한데, 테스트 느린게 더 못참겠다