본문 바로가기
IT

WireMock, 효율적인 API 테스트와 모의 서버 활용 가이드

by kuja-hazzy-story 2024. 11. 16.
반응형

 

오늘날 소프트웨어 개발에서는 다양한 외부 API와의 통합이 필수적입니다. 애플리케이션이 사용자에게 풍부한 기능을 제공하려면 외부 API를 효과적으로 활용하는 것이 중요한데, 여기서 발생하는 문제는 테스트 및 안정성입니다. 외부 API가 준비되지 않았거나 일관되지 않은 응답을 제공할 때, 어떻게 효율적으로 개발하고 테스트할 수 있을까요? 이러한 고민을 해결해주는 도구가 바로 WireMock입니다.


WireMock이란 무엇인가?

WireMock은 외부 API와의 상호 작용을 모방할 수 있는 HTTP 기반의 API 모킹(mocking) 프레임워크입니다. API 호출의 요청과 응답을 시뮬레이션할 수 있으며, 개발자가 테스트 환경에서 외부 시스템에 의존하지 않고도 HTTP 기반 통신을 검증할 수 있도록 도와줍니다.

WireMock의 기본 개념

  • 스터빙(Stubbing): 요청-응답 페어를 정의하여 특정 HTTP 요청에 대해 미리 설정된 응답을 반환합니다.
  • 요청 검증(Request Verification): WireMock 서버로 전달된 요청이 예상한 대로 이루어졌는지 확인합니다.
  • 지연 및 장애 시뮬레이션(Latency & Fault Simulation): 다양한 네트워크 상황을 시뮬레이션할 수 있습니다. 예를 들어, 응답이 지연되거나, 500 Internal Server Error와 같은 오류 상태를 설정할 수 있습니다.

WireMock의 주요 기능과 활용법

1. 요청-응답 스터빙

스터빙은 WireMock의 가장 기본적인 기능으로, 특정 요청이 주어졌을 때 사전에 정의된 응답을 반환하는 것입니다. 예를 들어, REST API의 GET /users/123 요청에 대해 다음과 같은 JSON 응답을 반환하도록 설정할 수 있습니다:

stubFor(get(urlEqualTo("/users/123"))
    .willReturn(aResponse()
        .withHeader("Content-Type", "application/json")
        .withBody("{ \"id\": 123, \"name\": \"John Doe\" }")));

이렇게 정의하면 GET /users/123 요청이 들어올 때 WireMock은 해당 JSON 응답을 반환합니다. 이를 통해 개발자는 외부 API 서버가 없는 상황에서도 응답을 모방하여 테스트할 수 있습니다.

2. 요청 검증

테스트 중에 WireMock 서버로 전달된 HTTP 요청이 정확히 예상한 대로 이루어졌는지 확인할 수 있습니다. 이는 클라이언트가 올바른 URL을 호출하고 있는지, 올바른 HTTP 메서드를 사용했는지를 검증하는 데 유용합니다.

verify(getRequestedFor(urlEqualTo("/users/123"))
    .withHeader("Content-Type", equalTo("application/json")));

요청 검증은 특히 API 호출이 복잡하거나 다양한 조건에 따라 다르게 동작하는 경우 필수적인 기능입니다. 이를 통해 코드의 정확성을 확인하고 잠재적인 버그를 조기에 발견할 수 있습니다.

3. 지연 및 장애 시뮬레이션

실제 환경에서는 네트워크가 불안정하거나 외부 API가 일시적으로 사용할 수 없는 경우가 자주 발생합니다. WireMock은 이러한 상황을 시뮬레이션하여 애플리케이션의 복원력(resilience)을 테스트할 수 있습니다.

  • 응답 지연: API 호출이 느려지는 상황을 재현할 수 있습니다. 예를 들어, 응답이 3초 지연되도록 설정할 수 있습니다.
stubFor(get(urlEqualTo("/slow-api"))
    .willReturn(aResponse()
        .withFixedDelay(3000) // 3초 지연
        .withBody("Delayed response")));
  • 오류 응답: 500 Internal Server Error와 같은 응답을 반환하도록 설정하여 애플리케이션이 예외 상황을 어떻게 처리하는지 테스트할 수 있습니다.
stubFor(get(urlEqualTo("/error-api"))
    .willReturn(aResponse()
        .withStatus(500)
        .withBody("Internal Server Error")));

WireMock 사용의 주요 이점

1. 외부 의존성 격리

개발 과정에서 외부 API가 준비되지 않았거나 접근할 수 없는 경우가 있습니다. WireMock은 외부 의존성을 효과적으로 격리하여 애플리케이션이 외부 시스템에 의존하지 않고도 기능을 검증할 수 있게 해줍니다. 이를 통해 다음과 같은 상황에서 도움이 됩니다:

  • API가 아직 구현되지 않은 경우: 새로운 API가 개발 중인 경우에도 WireMock을 사용해 테스트를 미리 수행할 수 있습니다.
  • 비용 절감: 외부 API 호출이 비용을 발생시키는 경우(예: 클라우드 서비스 API)에도 WireMock으로 비용을 절약할 수 있습니다.

2. 테스트 신뢰성 향상

외부 API는 종종 일관되지 않은 응답을 제공하거나, 네트워크 상태에 따라 응답이 달라질 수 있습니다. WireMock은 이러한 불확실성을 제거하고 일관된 테스트 결과를 보장합니다. 또한, 테스트가 외부 환경의 영향을 받지 않으므로 안정적인 테스트 자동화를 구축할 수 있습니다.

3. 다양한 시나리오 테스트

WireMock을 통해 정상적인 응답뿐만 아니라 다양한 예외 상황을 시뮬레이션할 수 있습니다. 예를 들어:

  • 서버가 과부하 상태일 때: WireMock을 사용해 API 응답이 과도하게 지연되거나 오류를 반환하도록 설정하여 애플리케이션의 성능을 점검할 수 있습니다.
  • 잘못된 데이터 처리: 의도적으로 API 응답에 잘못된 데이터를 포함시켜 애플리케이션의 오류 처리 로직을 테스트할 수 있습니다.

WireMock 설치 및 설정 가이드

WireMock은 설치 및 설정이 매우 간단합니다. Java 프로젝트의 경우 Maven이나 Gradle과 같은 빌드 도구를 사용해 WireMock을 추가할 수 있습니다.

Maven 설정

pom.xml에 다음 의존성을 추가합니다:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-jre8</artifactId>
    <version>2.35.0</version>
    <scope>test</scope>
</dependency>

이제 WireMock을 사용하여 테스트를 수행할 수 있습니다. Java 코드에서 WireMock 서버를 시작하고, 다양한 요청-응답 시나리오를 설정한 후, API 통합 테스트를 쉽게 진행할 수 있습니다.


WireMock의 한계

WireMock은 강력한 도구이지만 몇 가지 한계도 있습니다:

  • 복잡한 상태 관리: WireMock은 단순한 요청-응답 모델에 적합하지만, 복잡한 상태를 가진 API를 시뮬레이션하는 데는 어려움이 있을 수 있습니다.
  • 성능 제한: 대규모 테스트나 성능 테스트에는 적합하지 않을 수 있습니다. 이 경우 실제 API를 호출하는 것이 더 현실적일 수 있습니다.

결론

WireMock은 API 통합 테스트에서 외부 시스템에 의존하지 않고도 다양한 시나리오를 테스트할 수 있는 훌륭한 도구입니다. 요청-응답 스터빙, 요청 검증, 네트워크 장애 시뮬레이션 등을 제공하여 신뢰성 높은 테스트 환경을 구성할 수 있습니다. 개발자는 WireMock을 활용해 더 안정적인 애플리케이션을 개발하고, 외부 API와의 통합 과정에서 발생할 수 있는 문제를 미리 점검할 수 있습니다.


 

반응형