테스트 분리의 필요성
각 팀의 테스트 룰에 맞추어 Unit test
, Integration test
를 작성하게 될 텐데 Integratio test
의 경우에 당연히도 Unit test
보다는 훨씬 느린 수행속도를 갖게 될 것 입니다.
사실 Integration test
를 개발을 하는 과정중에 매번 수행하게되면 생산성이 매우 낮아지게 될 것입니다. 이러한 이유로 인해 Unit test
와 Integration test
는 분리해서 실행되어야 합니다.
보신분들도 있으시겠지만, 최근에 진행된 토스
개발자 컨퍼런스에서 가장 눈여겨 보았던 아래 세션을 통해서 분리의 필요성을 더 느낄수 있게 되었습니다. (테스트 약 3,000개 -> 6초 수행)
일반적으로 테스트 커버리지 확인시 jacoco
를 사용하게 되는데, IDE에서 선택적으로 테스트를 run 시키는 것 뿐만 아니라 gradle
test 과정에서도 unit test
만을 대상으로 할 수 있도록 필터링이 가능해야합니다.
Junit5 @Tag
Junit5
에서 제공하는 @Tag
기능을 사용하면 쉽게 구현 할 수 있습니다. Tag
기능을 통해 테스트들을 subset으로 묶어주는 기능으로, Tag
이름을 기반으로 필터링하는 기능까지 제공해 주고 있습니다.
저는 아래와 같이 사용합니다.
// IntegrationTest.java
@Tag("IntegrationTest")
@SpringBootTest
@AutoConfigureMockMvc
public abstract class IntegrationTest
{
@Autowired
protected MockMvc mockMvc;
}
// SomethingIntegrationTest.java
public class SomethingIntegrationTest extends IntegrationTest
{
@Test
void something_success()
{
}
}
// UnitTest.java
@Tag("UnitTest")
public abstract class UnitTest
{
}
// SomethingUnitTest.java
public class SomethingUnitTest extends UnitTest
{
@Test
void something_success()
{
}
}
abstract class에 tag를 선언해두고 테스트 목적에 따라 extends 해서 간단하게 설정 할 수 있습니다. 태그를 설정해두면 아래와 같이 테스트를 분리해서 사용 가능합니다.
- IntelliJ IDEA 설정
- gradle 설정
// build.gradle
test {
useJUnitPlatform{
includeTags 'UnitTest'
excludeTags 'IntegrationTest'
}
}
task integrationTest(type: Test) {
useJUnitPlatform{
includeTags 'IntegrationTest'
excludeTags 'UnitTest'
}
}
위의 설정들을 통해 IDE, gradle 모두에서 Tag
기반으로 테스트를 필터링해서 수행 시킬 수 있습니다. 테스트 커버리지 확인시에도 물론 Unit test
만 으로 측정되게 됩니다.