도커 컴포즈, Gradle 6, JUnit5 를 이용해 외부 모듈과 통합 테스트 자동화하기
외부 모듈과 상호작용하는 기능의 통합 테스트에 관한 이야기입니다.
JUnit 5 @Tag 애너테이션을 이용한 테스트 분류
JUnit 5 버전에서는 테스트를 다양하게 분류할 수 있도록 @Tag 애너테이션을 지원합니다.
먼저 아래와 같이 문자열을 이용해 테스트들을 분류합시다.
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
public class ManyTest {
@Tag("integration")
@Test
public void integrationTest1() {}
@Tag("integration")
@Test
public void integrationTest2() {}
@Tag("unit")
@Test
public void unitTest(){}
@Test
public void untaggedTest(){}
}
@Tag의 속성값을 이용해 분류한 테스트들을 일반 테스트(integration 태그만 제외) 태스트와 통합 테스트 태스크로 나눠 담아보겠습니다.
Gradle에 아래 코드를 추가합니다.
build.gradle
test {
useJUnitPlatform() {
excludeTags 'integration'
}
}
task integrationTest(type: Test, group: 'verification') {
useJUnitPlatform {
includeTags 'integration'
}
}
test 태스크는 모든 테스트를 수행하지만, integrationTest 태스크는 integration으로 태그된 테스트만 수행합니다.
Gradle 6, Docker-compose로 자동화하기
자동화된 통합 테스트를 위해서는 테스트 대상과 통신하는 모듈,서비스가 테스트 시작 전에 자동으로 켜지고,
전체 테스트가 끝나면 내려가야 됩니다. (지금까지 일일이 켰다껐다를 반복했으나, 더 이상 참을 수가 없다...)
저는 도커 컴포즈와 Gradle을 이용했습니다.
테스트 대상 프로젝트의 루트에 docker-compose.yml 파일을 작성합니다.
docker-compose.yml
version: "3.0"
services:
member-service:
build: ../member-service
ports:
- 8081:8081
restart: on-failure
테스트 대상은 테스트를 위해 member-service 와 통신해야 합니다.
member-service 루트에는 Dockerfile 을 작성.
FROM openjdk:11
RUN mkdir /app
ADD build/libs/member-service-0.0.1.jar /app
CMD [ "java", "-jar", "/app/member-service-0.0.1.jar" ]
build.gradle 파일을 수정합니다.
...
test {
useJUnitPlatform() {
excludeTags 'integration'
}
}
task integrationTest(type: Test, group: 'verification') {
doFirst{
exec {
try{
println("docker-compose up...")
commandLine("docker-compose","up","-d","--build")
}catch (Exception e){
e.printStackTrace()
println("docker-compsoe down...")
commandLine("docker-compose","down")
throw new RuntimeException("test calceled.")
}
}
}
doLast {
exec {
println("docker-compose down...")
commandLine("docker-compose","down")
}
}
useJUnitPlatform {
includeTags 'integration'
}
}
통합 테스트 시작 전, doFirst 안의 코드를 실행하면서 도커 컴포즈에 있는 서버를 올립니다.
그와중에 예외가 발생할 경우 도커 컨테이너들을 내리고 런타임 에러를 발생시켜 테스트를 취소시킵시다.
테스트가 끝난 경우에도 도커 컨테이너를 내릴 수 있도록 해주면 끝!
이제 통합테스트마다 다른 서버들을 켰다 껐다 할 필요없이 integrationTest 태스크를 이용해 자동으로 테스트가 가능해졌습니다.