본문 바로가기
🔓 영구 노트

유닛 테스트와 통합 테스트를 gradle 명령어로 분리하자

by 파랭이가 룰루랄라 2023. 2. 18.

많은 테스트와 기능이 있는 프로젝트에서 리팩토링 또는 기능 추가를 하게 된다면 현재 작성하고 있는 코드가 다른 코드에 영향을 미치고 있지는 확인하기 위해 테스트를 여러 번 실행하게 됩니다.

 

이때, 통합 테스트와 유닛 테스트가 같은 패키지 하위에 있다면 통합 테스트 외부 의존성 설정 시간 때문에 테스트에 많은 시간을 사용합니다.
(근처 카페에서 커피 포장해 와도 테스트가 실행 중일 수 있습니다...🤣🤣)

 

유닛 테스트와 통합 테스트의 실행 목적을 스피커에 빗대어 나름의 생각을 정리하면 다음과 같습니다.

  • 유닛 테스트: 재생을 누르면 내부 회로가 재생 신호를 받는가? 내부 회로는 다음 재생해야 할 음성이 무엇인지 알 수 있는가? 내부 회로는 스피커로 재생해야 할 음성을 전송할 수 있는가?
  • 통합 테스트: 재생 버튼을 누르면 음성이 나오는가?

유닛 테스트는 통합 테스트에 비해 서비스의 내부 동작을 상세하게 검증하는 것을 알 수 있습니다.

그렇다면 개발을 할 때 실행하는 테스트의 비중을 따졌을 때 유닛 테스트와 통합 테스트 중 무엇이 더 많을까요?

(나름의 생각을 정리해 보는 것도 좋을 것 같습니다)

 

결과적으로 유닛 테스트와 통합 테스트는 검증하고자 하는 범위와 기능이 다릅니다.

따라서 유닛 테스트와 통합 테스트의 환경을 물리적으로 나눠 관리하게 된다면 필요에 따라 원하는 테스트를 실행할 수 있기 때문에 테스트 실행 시간을 절약할 수 있다고 생각하여 gradle을 사용하여 테스트 환경을 물리적으로 분리하는 기능을 구현하였습니다.

(예시는 spring boot, kotlin gradle-kotlin을 사용하여 구현되었습니다.)

통합 테스트, 유닛 테스트 분리 in gradle

보통 gradle 프로젝트에서는 아래와 같이 useJuintPlatform()을 사용하여 junit 테스트를 실행합니다.

tasks.named<Test>("test") {  
    useJUnitPlatform()  
}

모든 설정을 하면 결과적으로 아래와 같이 3가지 명령어를 실행할 수 있게 됩니다.

  • test: 유닛 테스트와 통합 테스트를 모두 실행합니다.
  • unitTest: 유닛 테스트를 실행합니다.
  • integrationTest: 통합 테스트를 실행합니다.

먼저 sourceSets를 설정하여 unitTest와 integrationTest가 실행되는 환경을 선언해 주겠습니다.

gradle 명령어 등록에 필요한 리소스 설정

위와 같이 필요한 정보(코드)들이 어디에 있고, 의존성을 어디서 가져올지에 대한 정보를 설정해 줍니다.

자원을 설정하였으니 이제 gradle의 task로 등록해 줍니다.

gradle task 등록


위와 같이 integrationTestunitTest task를 등록해 줍니다.

 

코드를 작성한 후에 reload all gradle project를 실행하게 되면

 

gradle 명령어 추가

gradle task에서 integrationTest와 unitTest가 추가된 것을 알 수 있습니다.

 

여기까지 작성하면 이제 통합 테스트와 유닛 테스트를 코드 상에서 분리만 해주면 됩니다.
분리를 위해서 아래와 같이 integration-test 디렉터리 하위에 resource, kotlin 디렉터리를 생성해 줍니다.

src
|-- integration-test
|    |-- kotlin
|    |-- resource
|-- main
|    |-- kotlin 
|    |-- resource
|-- test
|    |-- kotlin
|    |-- resource

마지막으로 test를 아래와 같이 설정한 후에

test에 유닛 테스트와 통합 테스트가 실행될 수 있도록 설정

./gradlew clean build 명령어를 수행하면 unitTest, integrationTest가 포함된 것을 확인할 수 있습니다. 물론./gradlew clean unitTest,./gradlew clean integraionTest 명령어 또한 수행할 수 있습니다.

./gradlew clean build 실행 단계 중 일부

마무리

통합 테스트와 유닛 테스트를 분리하는 것은 관리 지점이 늘어난다 와 같은 단점이 있습니다.

 

따라서 테스트 환경을 분리하는 결정은 프로젝트에 적용할 경우 얻을 수 있는 이점이 구체적일 때 사용해야 합니다. 복잡한 구조, 많은 외부 의존성을 가지고 있는 프로젝트에서는 유용하게 작용할 수 있지만 간단한 구조, 적은 외부 의존성을 가지고 있는 프로젝트에서는 프로젝트의 가독성을 떨어뜨릴 수 있습니다.

 

또한 유닛 테스트와 통합 테스트를 분리하는 것은 절대적인 테스트 시간을 줄이는 것은 아닙니다.
테스트를 분리하는 것도 좋은 선택일 수 있지만 근본적으로 필요한 테스트를 효율적으로 작성하는 것이 기본이 되어야 할 것 같습니다.

댓글