Kotest 특징과 Given-When-Then 패턴

Kotest 특징

  • 다양한 테스트 스타일: FunSpec, StringSpec, ShouldSpec, BehaviorSpec, FeatureSpec, WordSpec, FreeSpec, DescribeSpec 등 다양한 테스트 스타일을 지원하여 테스트 코드를 원하는 방식으로 작성할 수 있습니다.

  • 코틀린 DSL: 코틀린 DSL(Domain-Specific Language)을 사용하여 테스트 코드를 간결하고 읽기 쉽게 작성할 수 있습니다.

  • JUnit 호환성: JUnit 플랫폼 위에서 동작하므로 기존 JUnit 테스트와 함께 사용할 수 있습니다.

  • 확장성: 다양한 테스트 확장 기능(Property Testing, Data-Driven Testing 등)을 제공하여 복잡한 테스트 시나리오를 쉽게 구현할 수 있습니다.

  • Matchers: 다양한 Matcher를 제공하여 테스트 결과를 더욱 명확하게 표현할 수 있습니다.

  • 비동기 테스트 지원: 코루틴을 사용하여 비동기 테스트를 간편하게 작성할 수 있습니다.

Given-When-Then 패턴

Given-When-Then 패턴은 BDD(Behavior-Driven Development)에서 사용되는 테스트 작성 패턴으로, 테스트 시나리오를 세 단계로 나누어 작성합니다.

  • Given (준비): 테스트에 필요한 초기 상태를 설정합니다.
  • When (실행): 테스트 대상 코드를 실행합니다.
  • Then (검증): 실행 결과를 검증합니다.

Kotest는 Given-When-Then 패턴을 지원하는 BehaviorSpec 스타일을 제공합니다.

Kotest BehaviorSpec 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class CalculatorTest : BehaviorSpec({
    val calculator = Calculator()

    given("두 개의 숫자") {
        val a = 1
        val b = 2

        `when`("덧셈 연산을 수행하면") {
            val result = calculator.add(a, b)

            then("결과는 3이어야 한다") {
                result shouldBe 3
            }
        }
    }
})

Android Unit Test vs. Integration Test (Instrumented Test)

Unit Test (단위 테스트):

  • 목표: 앱의 가장 작은 단위인 개별 클래스나 메서드의 기능을 독립적으로 검증합니다.

  • 실행 환경: JVM (Java Virtual Machine) 상에서 실행되며, Android 프레임워크에 대한 의존성 없이 테스트를 수행합니다.

  • 테스트 대상: ViewModel, Repository, UseCase, Data Model 등

  • 도구: JUnit, Mockito, Truth, MockK 등

  • 장점:

    • 빠른 실행 속도: Android 프레임워크를 실행하지 않으므로 테스트 속도가 매우 빠릅니다.
    • 격리된 환경: 외부 요인에 영향을 받지 않고 독립적으로 테스트할 수 있습니다.
    • 높은 재현성: 동일한 입력에 대해 항상 동일한 결과를 보장합니다.
  • 단점:

    • Android 의존성 테스트 불가: Android 프레임워크(Context, Activity, View 등)와의 상호 작용을 테스트할 수 없습니다.

    • Mock 객체 필요: 외부 의존성을 가진 경우 Mock 객체를 사용하여 의존성을 대체해야 합니다.

Integration Test (Instrumented Test) (통합 테스트):

  • 목표: 여러 컴포넌트 간의 상호 작용을 테스트하거나, 실제 Android 환경에서 앱의 동작을 검증합니다.
  • 실행 환경: Android 기기 또는 에뮬레이터에서 실행됩니다.
  • 테스트 대상: Activity, Fragment, Service, Content Provider 등
  • 종류:
    • UI 테스트 (Espresso): 사용자 인터페이스 요소의 동작을 테스트합니다.
    • 통합 테스트: 여러 컴포넌트 간의 상호 작용을 테스트합니다.
  • 도구: Espresso, UI Automator, Robolectric 등
  • 장점:
    • 실제 환경 테스트: 실제 Android 환경에서 앱의 동작을 테스트할 수 있습니다.
    • Android 의존성 테스트 가능: Android 프레임워크와의 상호 작용을 테스트할 수 있습니다.
  • 단점:
    • 느린 실행 속도: Android 환경을 실행해야 하므로 테스트 속도가 상대적으로 느립니다.
    • 낮은 재현성: 외부 요인(네트워크, 다른 앱 등)에 의해 테스트 결과가 달라질 수 있습니다.