Common/Testing

테스트 스텁, 테스트 드라이버란?

Seyun(Marco) 2025. 2. 2. 16:21
728x90

서론

정보처리기사를 준비하던 중 2024년 1회 기출문제에 나왔던 문제에 대한 개념중에 도움될만한것을 한개씩 공부해보려고 한다. 이번 1회에서는 테스트 스텁, 테스트 드라이버, 테스트 슈트, 테스트 케이스에 대해서 정리해보려고 합니다.

테스트 스텁(Test Stub)

테스트 중인 모듈에서 호출하는 외부 의존성이나 컴포넌트의 동작을 미리 정의된 결과로 대체하는 것을 의미합니다. 테스트할 모듈이 외부 컴포넌트에 의존하지 않고 독립적으로 테스트할수 있게 하는 것으로 단위테스트에서 많이 사용됩니다.

주로 Top-down 테스트에서 사용되며, 외부 서비스, DB와 같은 I/O 의존성을 단절하고 결과를 정의합니다.

외부 서비스가 느리거나 해당 비용이 드는경우나 예측 불가능한 결과를 테스트하는 경우에 많이 사용합니다.

코드로 한번 살펴보도록 하겠습니다.

  • kotlin
interface ExternalPaymentGateway {
    fun makePayment(amount: Int): Boolean
}

class PaymentService(private val gateway: ExternalPaymentGateway) {
    fun processPayment(amount: Int): String {
        return if (gateway.makePayment(amount)) "Success" else "Failure"
    }
}

class StubPaymentGateway : ExternalPaymentGateway {
    override fun makePayment(amount: Int): Boolean {
        return true  // Always returns success
    }
}

외부 결제 서비스를 inteface로 만들어서 테스트 할때는 StubPaymentGateway라는 구현체를 가지고 진행하고, 실제 서비스에서는 실제 구현체로 하는 방식으로 Stub을 진행한 코드입니다.

  •  TypeScript
interface ExternalPaymentGateway {
    makePayment(amount: number): boolean;
}

class PaymentService {
    private gateway: ExternalPaymentGateway;

    constructor(gateway: ExternalPaymentGateway) {
        this.gateway = gateway;
    }

    processPayment(amount: number): string {
        return this.gateway.makePayment(amount) ? "Success" : "Failure";
    }
}

class StubPaymentGateway implements ExternalPaymentGateway {
    makePayment(amount: number): boolean {
        return true;  // Always returns success
    }
}

 

JavaScript, TypeScript도 Inteface를 지원하기 때문에 이런식으로 비슷하게 진행할수 있습니다.

  • Ruby
class PaymentService
  def initialize(gateway)
    @gateway = gateway
  end

  def process_payment(amount)
    @gateway.make_payment(amount) ? "Success" : "Failure"
  end
end

class StubPaymentGateway
  def make_payment(amount)
    true  # Always returns success
  end
end

Ruby에서는 Inteface가 없기 때문에 생성자를 이용하여 gateway를 받아서 갈아끼울수 있도록 처리합니다.


테스트 드라이버(Test Driver)

테스트하려는 하위 모듈을 호출하고 실행할 수 있도록 돕는 상위 수준의 코드입니다. 테스트 대상 모듈을 독립적으로 실행하고 결과를 검증하는 데 사용됩니다. 주로 Bottom Up 테스트에서 사용되며, 테스트 대상 모듈에 입력 데이터를 전달하고 결과를 수집하는 역할을 합니다. 개발 모듈이 완성되었지만 상위 모듈이 준비되지 않았거나, 하위 모듈의 동작을 개별적으로 검증할때 사용합니다.

간단한 코드 예제를 확인하겠습니다.

import kotlin.test.Test
import kotlin.test.assertContentEquals

class SortingModule {
    fun sort(numbers: IntArray): IntArray {
        return numbers.sortedArray()
    }
}

// 테스트 드라이버
class SortingModuleTest {

    @Test
    fun testSorting() {
        val sorter = SortingModule()
        val input = intArrayOf(5, 2, 8, 3)
        val expected = intArrayOf(2, 3, 5, 8)

        assertContentEquals(expected, sorter.sort(input))
    }
}

일반적인 단위테스트를 의미하는것으로 가깝습니다.

이번 예제는 간단하니 Kotlin로만 예제코드를 추가합니다.

정리

위 사진에서 확인해볼수 있듯이. Driver는 상위, Stub은 하위를 한다고 생각하면 좋습니다.

  Stub Driver
유형 Dummy codes Dummy codes
설명 자기 자신과 매개변수만 선언하고 실제로 아무작업도 하지 않은 루틴입니다. 나머지 코드는 이러한 매개변수의 값으로 쓸수 있습니다. 자기 자신과 매개변수만 선언하고 실제로 아무작업도 하지 않은 루틴입니다. 나머지 코드는 이러한 매개변수의 값으로 쓸수 있습니다.
사용되는 곳 Top Down Integration Bottom Up Integration
목적 하위 코드가 아직 개발되지 않았을 때 상위 수준의 코드를 테스트 할 수 있도록 합니다. 상위 코드가 아직 개발되지 않았을 때 하위 수준의 코드를 테스트할 수 있도록 합니다.

출처

https://www.differencebetween.info/difference-between-stub-and-driver

728x90
728x90