본문 바로가기

프로젝트/Techfork

[25/12/27] 오늘의 개발 일지 - 테스트 환경 구성

많이 늦었지만... 일지를 작성해봅니다.

 

 

오늘의 작업은 저번 게시글에서 작성한대로 테스트 환경을 구성 했습니다.

 

1. 테스트 설정 파일 구현

spring:
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        format_sql: true
        highlight_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect

  batch:
    jdbc:
      initialize-schema: always
    job:
      names: ''

  ai:
    anthropic:
      api-key: test-dummy-key
      chat:
        options:
          model: claude-3-5-haiku-20241022
          temperature: 0.3
          max-tokens: 8192
    openai:
      api-key: test-dummy-key
      timeout: 60
      chat:
        options:
          model: gpt-4o-mini
          temperature: 0.3
          max-tokens: 8192

logging:
  level:
    com.techfork: DEBUG
    org.springframework.batch: INFO
    org.hibernate.SQL: DEBUG
    org.hibernate.tool.schema: ERROR

다음과 같이 application-integrationtest.yml을 작성했고,

@ActiveProfiles("integrationtest")을 붙여 이 프로필로 테스트가 작동하도록 하였습니다.

 


2. DynamicPropertis 대신 ServiceConnection 어노테이션 활용

@Container
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("test");

@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", mysql::getJdbcUrl);
    registry.add("spring.datasource.username", mysql::getUsername);
    registry.add("spring.datasource.password", mysql::getPassword);
}

위의 코드는 설정값을 일일히 넣어줘야 하므로 매우 귀찮습니다만

 

import org.springframework.boot.testcontainers.service.connection.ServiceConnection;

@ServiceConnection
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0");

스프링부트의 ServiceConnection을 활용하면 매우 간단하게 설정이 가능합니다.

 

testImplementation 'org.springframework.boot:spring-boot-testcontainers'

이를 위해 다음의 스프링부트 테스트 컨테이너 의존성을 추가해주었습니다.

 

 

참고 자료

https://docs.spring.io/spring-boot/3.5/reference/testing/testcontainers.html#page-title


3. 통합테스트에서 @Transactional 대신 @AfterEach를 통한 정리

 

테스트 환경에서 트랜잭션 어노테이션은 커밋하는 대신 롤백을 일으켜,

테스트 데이터를 정리하는 수고를 덜어줍니다.

 

하지만 이는 실제 커밋이 이뤄지는 서비스 환경과 다르므로 예상치 못한 오류가 발생할 수 있습니다.

 

따라서 @Transactional을 제거하고, @AfterEach로 각 테스트 메서드 작동 이후 데이터를 정리하는 식으로 구성했습니다.

@AfterEach
void tearDown() {
    // 테스트 데이터 정리 (외래키 제약조건 순서 고려)
    postKeywordRepository.deleteAll();
    postRepository.deleteAll();
    techBlogRepository.deleteAll();
}

 

이를 통해 실제 환경과 매우 유사한 테스트 환경을 구성할 수 있었지만,

데이터가 커밋이 이뤄지고 제거하는 쿼리가 나가다보니 좀 더 시간적으로는 오래 소요되는 것을 확인했습니다.

 

 


4. 스프링 부트 버전 업그레이드 (3.5.6 -> 3.5.9)

 

@ServiceConnection 사용을 위해 공식문서를 찾아보던 중 3.5.x의 stable 버전이 3.5.9임을 확인했습니다.

단순히 마지막 숫자의 변경은 하위 호환성을 유지하는 버그 수정이므로,

걱정없이 올렸습니다만...

 

혹시 몰라 테스트 코드를 모두 돌려보고 api 테스트를 진행했습니다.

왜 각 api에 대해 테스트 코드가 필요한지 알겠더군요.

버전 잘못 올려서 api들이 잘 작동할지 안 날지를 수동으로 직접 진행하기는 버겁다는 생각이 들었습니다.

 

나머지 api들도 모두 테스트 코드 작성을 해보도록 하겠습니다.