코틀린에서 테스트코드를 처음 작성하시는 분들을 위한 JUnit 5 단위테스트 작성법을 설명드리려고 합니다. 테스트코드가 익숙지 않으신 분들도 이해하실 수 있게 최대한 쉽게 설명하려고 합니다. 테스트코드가 아예 처음이시라면 저의 이전 포스팅인 코틀린에서 JUnit 5를 사용해 테스트코드 작성하기를 꼭 읽고 와주세요!
1. 단위테스트란?
단위테스트란, 프로그램 전체를 테스트하는 것이 아닌 독립된 작은 단위의 기능만을 테스트하는 것을 말합니다. 테스트가 익숙하지 않으신 분들이라면 이 말이 바로 이해가 되지 않으실 겁니다. 예시 코드를 보면서 설명해 보겠습니다. 객체를 하나 정의해 보도록 하죠.
class Car(val name: String, speed: Int) {
var position: Int = 0
private set
var speed: Int = speed
private set
fun move() {
position += speed
}
fun speedUp() {
speed++
}
fun speedDown() {
speed--
}
}
이 코드에서 저는 Car
객체를 정의했고, move()
를 하게 되면 position
이 speed
만큼 증가하도록 설정했습니다. 그리고 저는 실제로 Car
의 move()
를 호출하면 position
이 올바르게 증가하는지를 테스트해보고 싶어 졌습니다. 즉, 프로그램 전체를 테스트하는 것이 아니라 '움직이다'라는 Car
의 기능 하나만을 테스트하려고 하는 것입니다. 이것이 바로 단위테스트입니다.
2. 단위테스트 작성하기
단위테스트를 할 때에는 일반적으로 src/main 내의 패키지 구조를 src/test 내의 패키지 구조와 똑같이 일치시키고, 같은 패키지 안에 테스트 클래스를 생성하게 됩니다.
위의 이미지에서 보시다시피 main 패키지와 test 패키지 안의 패키지 구조가 동일하죠? 저는 Car
클래스를 src/main/kotlin/racingcar/model에 생성했습니다. 그렇다면 Car
를 테스트하는 테스트클래스는 이름을 'Test'를 붙여서 CarTest
로 짓고, src/test/kotlin/racingcar/model 안에 생성하면 됩니다. 그리고 이 클래스에서 단위테스트를 작성합니다. move()
를 테스트하는 코드는 다음과 같이 작성해 볼 수 있겠습니다.
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
class CarTest {
@Test
fun `자동차는 이동하면 position이 speed만큼 증가한다`() {
// given
val alsongCar = Car(name = "alsong", speed = 3)
// when
alsongCar.move()
// then
assertThat(alsongCar.position).isEqualTo(3)
}
}
이 테스트는 JUnit 5가 제공하는 테스트 함수이고, AssertJ를 사용해 단언문을 작성한 것입니다. given절에서는 alsongCar
인스턴스를 생성했고, when절에서는 alsongCar
를 이동시켰습니다. speed
가 3이기 때문에 이 기능이 제 의도대로 동작했다면 position
이 0에서 3 증가해서 3이 되었어야 합니다. 따라서 저는 then절에서 "alsongCar
의 position
이 3
이다"라고 단언했습니다. 실제로 테스트를 실행시켜 보면 제 테스트가 성공했는지 확인할 수 있습니다.
테스트 성공! 👍
그럼 이제 Car
객체의 다른 기능들도 테스트를 해볼까요? 제가 정의한 Car
는 move()
말고도 두 가지 기능(함수)이 더 있습니다. speedUp()
과 speedDown()
함수죠. 이 두 함수도 단위테스트를 작성해 보도록 합시다.
@Test
fun `자동차는 속도를 증가시키면 speed가 1 증가한다`() {
// given
val alsongCar = Car(name = "alsong", speed = 3)
// when
alsongCar.speedUp()
// then
assertThat(alsongCar.speed).isEqualTo(4)
}
@Test
fun `자동차는 속도를 감소시키면 speed가 1 감소한다`() {
// given
val alsongCar = Car(name = "alsong", speed = 3)
// when
alsongCar.speedDown()
// then
assertThat(alsongCar.speed).isEqualTo(2)
}
위와 같이 작성할 수 있겠네요! 이제 우리는 Car
객체의 각각의 기능 단위를 잘 테스트한 것입니다.
어쩌면 이렇게 생각하실 수도 있겠습니다. "아니 너무 당연한 것을 테스트한거 아니야? 단위테스트라는게 이렇게 쉬운 기능만을 테스트하는거라면 테스트가 필요 없어 보이는데.." 저도 이렇게 생각할 때가 있었는데요, 이번 포스팅에서는 예시를 들기 위해 정말 단순한 기능을 테스트 한 것이지만 실제로 도메인을 설계하다 보면 훨씬 복잡한 기능이 마구 등장하게 됩니다. 그런 복잡한 기능들은 정상 동작하는지 직관적으로 알기 어렵죠. 그럴 때에는 단위테스트가 빛을 발하게 된답니다!
'Test' 카테고리의 다른 글
[Test] Junit 5와 AssertJ를 같이 사용하는 이유 (0) | 2025.01.26 |
---|---|
[Test] 코틀린에서 JUnit 5를 사용해 테스트코드 작성하기 기초 (0) | 2025.01.12 |