티스토리 뷰

Spring Boot에 starter-test 라이브러리를 추가하면 JUnit API를 이용하여 테스트 코드를 작성할 수 있습니다.

테스트 코드를 작성하고 검증할 때 검증하고자 하는 값이 실행환경에 따라 동적으로 변경된다면 그 실행환경에 맞게끔 설정을 해줘야 합니다.

Spring에서는 ActiveProfilesResolver 라는 인터페이스를 제공해주는데 이 인터페이스를 활용하여 처리할 수 있습니다.

간단히 예제코드를 보면서 내용을 살펴보도록 하겠습니다.

테스트 환경

  • Spring Boot
  • Gradle

테스트 코드

위 코드는 ActiveProfiles 라는 어노테이션을 통해 테스트 코드를 실행할 Spring Profile을 지정해주고 해당 Profile에 맞는 Property를 조회해오는 코드입니다.

 

 

결과는 성공입니다. ActiveProfiles에 Spring Profile을 local로 지정해두고 application.yml 파일에 Spring Profile이 local로 active된 Property의 값을 가져와서 검증하였고 결과는 잘 수행되었습니다.

 

그런데 개발된 애플리케이션을 development 환경에서 빌드할 때는 Spring Profile을 development로 맞춰야 하고 production 환경에서 빌드할 때는 Spring Profile을 production으로 해주어야 합니다.

 

위 방식처럼 사용하게 될 경우 해당 처리를 하기 위해선 값을 매번 바꿔서 빌드해야하는데 이러면 매우 번거롭습니다.

이럴 때 Spring에서 제공해주는 ActiveProfilesResolver를 이용하면 테스트 코드 실행 시 동적으로 ActiveProfiles 어노테이션에 원하는 Profile을 주입해줄 수 있습니다. 이제 밑에서 한번 알아보도록 하겠습니다.

 

ActiveProfilesResolver 구현클래스 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.demo.resolver;
 
import org.springframework.test.context.ActiveProfilesResolver;
 
public class SpringActiveProfilesResolver implements ActiveProfilesResolver {
    private static final String SPRING_PROFILES_ACTIVE = "spring.profiles.active";
 
    @Override
    public String[] resolve(Class<?> testClass) {
        String property = System.getProperty(SPRING_PROFILES_ACTIVE);
        return new String[] {property};
    }
}
cs

ActiveProfilesResolver는 인터페이스입니다. 이 인터페이스의 구현 클래스를 생성하여 resolve 메서드를 오버라이딩 해줍니다. 그리고 resolve 메서드의 반환값이 적용할 Profile입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.example.demo.resolver.SpringActiveProfilesResolver;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assertions.*;
 
@SpringBootTest
@ActiveProfiles(resolver = SpringActiveProfilesResolver.class)
public class DemoApplicationTests {
 
    @Value("${spring.config.activate.on-profile}")
    private String profile;
 
    @Test
    @DisplayName("ActiveProfilesResolver를 이용하여 값을 local로 세팅하고 테스트한다.")
    void test() {
        assertEquals(profile, "local");
    }
}
cs

ActiveProfiles 어노테이션의 resolver 속성에 구현클래스를 정의해줍니다.

 

 

사진 우측상단에 테스트 관련 파일명을 클릭 후 Edit Configuration을 클릭하면 위 사진이 나오게 됩니다.

빨간색 네모 영역 부분에 JVM 옵션 -Dspring.profiles.active=local을 설정해줍니다.

해당 값은 SpringActiveProfilesResolver에서 사용할 수 있게 됩니다.

 

ActiveProfilesResolver를 이용한 테스트 - Run test using (Intellij)

Spring Profile값을 ActiveProfilesResolver 인터페이스를 구현한 클래스에서 조회하도록 구성하고 테스트를 진행해보니 정상적으로 완료되었습니다. 

 

Run test using 대상을 Intellij -> Gradle로 변경

위에서 테스트한 내용들은 Run test using 대상을 Intellij로 설정해둔 상태로 진행하였습니다. 

 

하지만 테스트 코드를 IDE가 아니라 CI 서버에서 Cli로 진행할 경우 기본값(Gradle)이 적용됩니다. 

이렇게 되면 추가적인 구성이 필요합니다. Run test using 대상을 Gradle로 변경하고 진행해보겠습니다.

 

Run test using에 대한 내용은 여기를 확인해보시면 됩니다.

 

테스트 코드 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.example.demo.resolver.SpringActiveProfilesResolver;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assertions.*;
 
@SpringBootTest
@ActiveProfiles(resolver = SpringActiveProfilesResolver.class)
public class DemoApplicationTests {
 
    @Value("${spring.config.activate.on-profile}")
    private String profile;
 
    @Test
    @DisplayName("ActiveProfilesResolver를 이용하여 값을 development로 세팅하고 테스트한다.")
    void test() {
        assertEquals(profile, "development");
    }
}
cs

이제는 local이 아니라 development 서버에 배포한다고 가정하고 진행해보겠습니다.

 

 

Cli로 테스트코드 실행

gradlew clean build -Dspring.profiles.active=development test --debug

터미널에서 해당 커맨드로 빌드해보겠습니다. Gradle의 -D 속성으로 JVM 시스템 변수를 주입해줍니다.

그리고 상세한 내용을 보기 위해 debug 옵션을 켜두었습니다.



실행 로그를 확인해보니 Spring Profile 값이 정상적으로 주입되지 않았습니다.

테스트가 왜 실패하였는지 원인을 파악하기 위해 구글링을 하였고 스택오버플로우에서 관련 글을 발견하였고 다음과 같은 답변을 볼 수 있었습니다.

 

정리하자면 다음과 같습니다.

-D 옵션은 JVM 속성이고 -P는 Gradle의 속성입니다. 테스트가 새 JVM 환경에서 분기될 수 있기 때문에 -D 옵션은 테스트로 전파되지 않습니다. 사용하고 싶다면 -P로 전달받은 속성값을 systemProperty에 세팅하여 사용할 수 있습니다. 

 

Gradle의 Property를 System Property로 지정

Gradle의 Property 값들은 project라는 build.gradle파일에서 제공되는 변수에서 꺼내올 수 있습니다.

Property가 존재할 경우 해당 값을 사용하고 없으면 local을 사용하게끔 설정해두었습니다.

그리고 이 값을 systemProperty에 spring.profiles.active라는 key에 설정해두었습니다.

 

ActiveProfilesResolver를 이용한 테스트 - Run test using (Gradle)

gradlew clean build -Pprofile=development test --debug

Cli 명령어를 위처럼 변경하여 실행해보겠습니다.

 

 

이번엔 정상적으로 Spring Profile이 주입되었고 테스트도 정상적으로 실행되었습니다.



 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함