Testing Codes/JUnit5

[JUnit5] @RepeatedTest 사용해 테스트 반복 실행하기

반복된 테스트가 필요한 이유

일반적으로 멀티 스레드 환경에서 동작하는 코드를 작성했을 때, 경쟁상태 문제로 인해 간헐적으로 버그가 날 수 있다. 이렇게 간헐적으로 버그를 발생 시키는 코드에 대한 테스트 코드를 작성하면 Flacky Test 문제가 생긴다.

*결과가 일관되지 않는 테스트를 :lacky Test 라고 부른다

이런 경우 JUnit4에서는 테스트를 반복하기 위해서는 반복하는 코드를 직접 넣어주어야 했고, 이렇게 하나의 테스트에서 반복해서 테스트를 실행한다면, 넣는다면 몇 번째 테스트에서 실패했는지, 몇 번이나 테스트를 실패했는지 알 수 없는 문제가 있었다.

@Test
fun dummyTest() {
    repeat(100) {
        runTest {
            val result = contentSearcher.searchByKeyword("Dummy")
            assertEquals(emptyList(), result)
        }
    }
}

 

이런 문제를 해결하기 위해 JUnit5에서는 @RepeatedTest라는 기능을 제공한다.

 

@RepeatedTest 사용해 테스트 반복하기

@RepeatedTest를 사용하면, 하나의 테스트를 몇 번 반복할지 정할 수 있으며, 각 테스트가 언제 실패했는지도 알 수 있다. 이를 확인하기 위해, 다음과 같이 calculate 연산을 만들어보자. calculate연산은 50%의 확률로 옳은 정답을 내고 50% 확률로 틀린 정답을 내는 연산이다. 

class SimpleTest {
    private fun calculate(): Int = if (Random.nextBoolean()) 2 else 3
    ...
}

 

이 연산을 100번 실행하는 테스트를 만들기 위해서는 @Test 대신 @RepeatedTest를 사용하면 된다. @RepeatedTest 어노테이션은 정수를 인자로 받으며, 받은 정수 만큼 반복된 연산을 실행한다.

class SimpleTest {
    private fun calculate(): Int = if (Random.nextBoolean()) 2 else 3

    @RepeatedTest(100)
    fun dummyTest() {
        val result = calculate()
        assertEquals(2, result)
    }
}

 

이제 테스트를 실행해보면 다음과 같은 결과를 볼 수 있다. 100번의 테스트 중 얼만큼이 성공하고 실패했는지 파악하는 것이 가능하다. 또한 개별 테스트가 어떤 값을 내면서 실패했는지도 확인이 가능하다.

그림1. RepeatedTest

 

 

정리

멀티 스레드 환경에서 연산이 병렬로 실행될 때 공유 상태가 변경되거나 한다면, 경쟁 상태 문제가 생길 수 있으며 이로 인해 결과가 일관적이지 않을 수 있다. 이런 경우 일반적인 테스트로는 이런 간헐적인 오류를 잡아내기 매우 어렵지만 @RepeatedTest를 사용하면 오류를 잡아내기 쉬워진다. 이 외에도 결과가 랜덤으로 나올 수 있는 많은 상황(시간에 의존적인 경우 등)에 @RepeatedTest를 사용해 코드에 어떤 문제가 있는지 잡아낼 수 있다.

반응형

 

이 글의 저작권은 Dev World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com