🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Microservices 테스트 전략 완벽 가이드 - 슬라이드 1/11
A

AI Generated

2025. 11. 5. · 65 Views

Microservices 테스트 전략 완벽 가이드

마이크로서비스 아키텍처에서 필수적인 테스트 전략을 단계별로 학습합니다. Unit 테스트부터 Contract 테스트, Integration 테스트까지 실전 예제로 익혀보세요.


카테고리:TypeScript
언어:TypeScript
메인 태그:#Microservices
서브 태그:
#UnitTest#IntegrationTest#ContractTest#E2ETest

들어가며

이 글에서는 Microservices 테스트 전략 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. Unit_Test_기본
  2. Integration_Test_API
  3. Contract_Test_Provider
  4. Contract_Test_Consumer
  5. Service_Mesh_Test
  6. Event_Driven_Test
  7. Database_Transaction_Test
  8. Performance_Load_Test
  9. Security_Auth_Test
  10. End_to_End_Test

1. Unit Test 기본

개요

개별 서비스의 비즈니스 로직을 독립적으로 테스트합니다. 외부 의존성을 모킹하여 빠르고 안정적인 테스트를 작성합니다.

코드 예제

```typescript
describe('UserService', () => {
  it('should create user with valid data', async () => {
    const mockRepo = { save: jest.fn().mockResolvedValue({ id: 1 }) };
    const service = new UserService(mockRepo);

    const result = await service.createUser({ name: 'John' });

    expect(result.id).toBe(1);
    expect(mockRepo.save).toHaveBeenCalledTimes(1);
  });
});

### 설명

Jest를 사용해 UserService의 createUser 메서드를 테스트합니다. 데이터베이스 의존성을 모킹하여 순수 로직만 검증합니다.

---

## 2. Integration_Test_API

### 개요

실제 데이터베이스와 연동하여 API 엔드포인트를 테스트합니다. 서비스 간 통합이 올바르게 작동하는지 확인합니다.

### 코드 예제

```typescript
```typescript
describe('POST /users', () => {
  it('should create user and return 201', async () => {
    const response = await request(app)
      .post('/users')
      .send({ name: 'John', email: 'john@test.com' });

    expect(response.status).toBe(201);
    expect(response.body.name).toBe('John');
  });
});

### 설명

Supertest를 활용해 실제 HTTP 요청을 보내고 응답을 검증합니다. 데이터베이스에 실제로 저장되는지 확인합니다.

---

## 3. Contract_Test_Provider

### 개요

Consumer와 Provider 간의 계약을 검증합니다. Pact를 사용해 API 스펙이 양측에서 일치하는지 테스트합니다.

### 코드 예제

```typescript
```typescript
describe('User Service Provider', () => {
  it('should fulfill user creation contract', async () => {
    await provider.addInteraction({
      state: 'user does not exist',
      uponReceiving: 'a request to create user',
      withRequest: { method: 'POST', path: '/users' },
      willRespondWith: { status: 201, body: { id: 1 } }
    });

    await provider.verify();
  });
});

### 설명

Provider 측에서 Consumer가 기대하는 응답 형식을 제공하는지 검증합니다. API 변경 시 호환성을 보장합니다.

---

## 4. Contract_Test_Consumer

### 개요

Consumer 관점에서 Provider API를 호출할 때 기대하는 계약을 정의합니다. Mock 서버로 독립적으로 테스트합니다.

### 코드 예제

```typescript
```typescript
describe('Order Service Consumer', () => {
  it('should get user data', async () => {
    await provider.addInteraction({
      uponReceiving: 'get user request',
      withRequest: { method: 'GET', path: '/users/1' },
      willRespondWith: { status: 200, body: { id: 1, name: 'John' } }
    });

    const user = await orderService.getUserById(1);
    expect(user.name).toBe('John');
  });
});

### 설명

Order Service가 User Service를 호출할 때 기대하는 응답을 정의합니다. 실제 서비스 없이도 테스트 가능합니다.

---

## 5. Service_Mesh_Test

### 개요

서비스 간 통신에서 발생할 수 있는 네트워크 장애를 시뮬레이션합니다. 재시도, 타임아웃 정책을 검증합니다.

### 코드 예제

```typescript
```typescript
describe('Payment Service Resilience', () => {
  it('should retry on network failure', async () => {
    nock('http://bank-api').get('/balance').times(2).replyWithError('timeout');
    nock('http://bank-api').get('/balance').reply(200, { balance: 1000 });

    const balance = await paymentService.getBalance();

    expect(balance).toBe(1000);
  });
});

### 설명

Nock으로 네트워크 장애를 모킹하고 재시도 로직이 올바르게 작동하는지 확인합니다. 3번째 시도에서 성공하는 시나리오입니다.

---

## 6. Event_Driven_Test

### 개요

비동기 이벤트 기반 통신을 테스트합니다. 메시지 큐를 통한 서비스 간 이벤트 발행과 구독을 검증합니다.

### 코드 예제

```typescript
```typescript
describe('Order Created Event', () => {
  it('should trigger inventory update', async (done) => {
    const eventBus = new EventEmitter();
    const inventory = new InventoryService(eventBus);

    eventBus.on('order.created', (data) => {
      expect(data.productId).toBe('P001');
      done();
    });

    await orderService.createOrder({ productId: 'P001', qty: 5 });
  });
});

### 설명

주문 생성 이벤트가 발행되면 재고 서비스가 이를 수신하는지 확인합니다. 이벤트 기반 아키텍처의 핵심 패턴입니다.

---

## 7. Database_Transaction_Test

### 개요

분산 트랜잭션 시나리오에서 데이터 일관성을 테스트합니다. Saga 패턴의 보상 트랜잭션을 검증합니다.

### 코드 예제

```typescript
```typescript
describe('Order Saga', () => {
  it('should rollback on payment failure', async () => {
    const mockPayment = jest.fn().mockRejectedValue('insufficient funds');
    const saga = new OrderSaga(mockPayment);

    await expect(saga.createOrder({ total: 1000 })).rejects.toThrow();

    const order = await orderRepo.findById(1);
    expect(order.status).toBe('CANCELLED');
  });
});

### 설명

결제 실패 시 주문이 자동으로 취소되는지 확인합니다. 보상 트랜잭션으로 데이터 일관성을 유지합니다.

---

## 8. Performance_Load_Test

### 개요

마이크로서비스의 부하 처리 능력을 테스트합니다. 동시 요청 처리와 응답 시간을 측정합니다.

### 코드 예제

```typescript
```typescript
import autocannon from 'autocannon';

describe('API Performance', () => {
  it('should handle 100 requests/sec', async () => {
    const result = await autocannon({
      url: 'http://localhost:3000/products',
      connections: 10,
      duration: 10
    });

    expect(result.requests.average).toBeGreaterThan(100);
    expect(result.latency.p99).toBeLessThan(500);
  });
});

### 설명

Autocannon으로 초당 100개 요청을 보내고 99퍼센타일 응답 시간이 500ms 이하인지 검증합니다.

---

## 9. Security_Auth_Test

### 개요

마이크로서비스 간 인증과 권한 부여를 테스트합니다. JWT 토큰 검증과 역할 기반 접근 제어를 확인합니다.

### 코드 예제

```typescript
```typescript
describe('Protected Endpoint', () => {
  it('should reject invalid token', async () => {
    const response = await request(app)
      .get('/admin/users')
      .set('Authorization', 'Bearer invalid-token');

    expect(response.status).toBe(401);
  });

  it('should allow valid admin token', async () => {
    const token = generateToken({ role: 'admin' });
    const response = await request(app).get('/admin/users').set('Authorization', `Bearer ${token}`);
    expect(response.status).toBe(200);
  });
});

### 설명

잘못된 토큰은 거부하고 유효한 관리자 토큰은 허용하는지 확인합니다. API 보안의 핵심 테스트입니다.

---

## 10. End_to_End_Test

### 개요

전체 마이크로서비스 시스템의 주요 사용자 시나리오를 테스트합니다. 여러 서비스가 협력하는 흐름을 검증합니다.

### 코드 예제

```typescript
```typescript
describe('Complete Order Flow', () => {
  it('should process order from creation to delivery', async () => {
    const user = await createTestUser();
    const product = await createTestProduct();

    const order = await request(app).post('/orders').send({ userId: user.id, productId: product.id });
    expect(order.body.status).toBe('PENDING');

    await processPayment(order.body.id);
    await updateInventory(product.id);

    const finalOrder = await getOrder(order.body.id);
    expect(finalOrder.status).toBe('DELIVERED');
  });
});

### 설명

주문 생성, 결제, 재고 업데이트, 배송 완료까지 전체 플로우를 테스트합니다. 실제 사용자 경험을 시뮬레이션합니다.

---

## 마치며

이번 글에서는 Microservices 테스트 전략 완벽 가이드에 대해 알아보았습니다.
총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

### 관련 태그

#Microservices #UnitTest #IntegrationTest #ContractTest #E2ETest
#Microservices#UnitTest#IntegrationTest#ContractTest#E2ETest#TypeScript

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.