[kotlin] Hamcrest의 테스트 코드 표준화

Hamcrest는 Java와 Kotlin을 포함한 여러 언어에서 테스트 코드의 가독성을 높이고 표현력을 향상시키는 장점을 가지고 있습니다. 하지만 프로젝트 팀에서 Hamcrest를 사용할 때 어떤 방식으로 테스트 코드를 작성하는 것이 좋을지에 대한 표준이 필요할 수 있습니다. 이 글에서는 Kotlin을 사용하는 환경에서 Hamcrest를 사용한 테스트 코드에 대한 표준화된 방식을 알아보겠습니다.

테스트 함수 네이밍

첫 번째 규칙은 테스트 함수의 네이밍 규칙입니다. 메소드명은 테스트하는 메소드의 의도를 직관적으로 나타내야 합니다. 일반적으로 [테스트 대상][상황][기대 동작] 형식으로 네이밍하는 것이 일반적입니다.

@Test
fun calculateTotalPrice_withEmptyCart_shouldReturnZero() {
    // 테스트 코드
}

Matcher 사용

Hamcrest를 사용할 때는 Matcher를 이용하여 테스트 코드를 작성하는 것이 일반적입니다. 아래는 일반적인 Matcher를 사용한 테스트 코드의 예시입니다.

@Test
fun calculateTotalPrice_withEmptyCart_shouldReturnZero() {
    val cart = ShoppingCart()
    val totalPrice = cart.calculateTotalPrice()

    assertThat(totalPrice, `is`(equalTo(0)))
}

Custom Matcher 작성

복잡한 비교 로직이 필요한 경우에는 Custom Matcher를 작성하여 테스트 코드의 가독성을 높일 수 있습니다. 예를 들어, 장바구니에 특정 상품이 포함되어 있는지를 검증하는 것을 Custom Matcher로 작성할 수 있습니다.

fun hasProduct(productName: String): Matcher<ShoppingCart> {
    return object : BaseMatcher<ShoppingCart>() {
        override fun describeTo(description: Description) {
            description.appendText("cart has product $productName")
        }

        override fun matches(item: Any): Boolean {
            if (item is ShoppingCart) {
                return item.products.any { it.name == productName }
            }
            return false
        }
    }
}

@Test
fun addToCart_shouldContainAddedProduct() {
    val cart = ShoppingCart()
    cart.addProduct(Product("apple", 1))

    assertThat(cart, hasProduct("apple"))
}

결론

Hamcrest를 이용하여 테스트 코드를 작성할 때는 팀원들 간에 일관된 방식으로 작성하기 위한 표준화된 규칙이 필요합니다. 테스트 함수의 네이밍 규칙과 Matcher 사용법에 대한 표준을 정의하여 프로젝트에서 일관된 테스트 코드를 작성할 수 있도록 노력해야 합니다.

참고: