한국어

Supertest를 사용한 API 테스트에 중점을 둔 통합 테스트 종합 가이드. 설정, 모범 사례, 고급 기술을 다루어 견고한 애플리케이션 테스트를 보장합니다.

통합 테스트: Supertest로 API 테스트 마스터하기

소프트웨어 개발 영역에서 개별 구성 요소가 독립적으로 올바르게 작동하는지 확인하는 것(단위 테스트)은 매우 중요합니다. 하지만 이러한 구성 요소들이 서로 원활하게 함께 작동하는지 검증하는 것 또한 똑같이 중요합니다. 바로 이 지점에서 통합 테스트가 필요합니다. 통합 테스트는 애플리케이션 내의 여러 모듈 또는 서비스 간의 상호 작용을 검증하는 데 중점을 둡니다. 이 글에서는 통합 테스트, 특히 Node.js에서 HTTP 단언을 테스트하기 위한 강력하고 사용자 친화적인 라이브러리인 Supertest를 사용한 API 테스트에 대해 심도 있게 다룹니다.

통합 테스트란 무엇인가?

통합 테스트는 개별 소프트웨어 모듈을 결합하여 그룹으로 테스트하는 소프트웨어 테스트 유형입니다. 통합된 단위들 간의 상호 작용에서 발생하는 결함을 찾아내는 것을 목표로 합니다. 개별 구성 요소에 초점을 맞추는 단위 테스트와 달리, 통합 테스트는 모듈 간의 데이터 흐름과 제어 흐름을 검증합니다. 일반적인 통합 테스트 접근 방식은 다음과 같습니다:

API의 맥락에서 통합 테스트는 여러 API가 함께 올바르게 작동하는지, 그들 사이에 전달되는 데이터가 일관성이 있는지, 그리고 전체 시스템이 예상대로 작동하는지 검증하는 것을 포함합니다. 예를 들어, 상품 관리, 사용자 인증, 결제 처리를 위한 별도의 API를 가진 전자 상거래 애플리케이션을 상상해 보십시오. 통합 테스트는 이러한 API들이 올바르게 통신하여 사용자가 상품을 탐색하고, 안전하게 로그인하며, 구매를 완료할 수 있도록 보장합니다.

API 통합 테스트가 중요한 이유는 무엇인가?

API 통합 테스트는 여러 가지 이유로 매우 중요합니다:

글로벌 여행 예약 플랫폼을 생각해 봅시다. API 통합 테스트는 다양한 국가의 항공편 예약, 호텔 예약 및 결제 게이트웨이를 처리하는 API 간의 원활한 통신을 보장하는 데 가장 중요합니다. 이러한 API를 제대로 통합하지 못하면 잘못된 예약, 결제 실패, 좋지 않은 사용자 경험으로 이어져 플랫폼의 평판과 수익에 부정적인 영향을 미칠 수 있습니다.

Supertest 소개: API 테스트를 위한 강력한 도구

Supertest는 HTTP 요청을 테스트하기 위한 고수준 추상화 라이브러리입니다. 애플리케이션에 요청을 보내고 응답에 대한 단언을 수행하는 편리하고 유창한(fluent) API를 제공합니다. Node.js를 기반으로 구축된 Supertest는 특히 Node.js HTTP 서버 테스트를 위해 설계되었습니다. Jest나 Mocha와 같은 인기 있는 테스트 프레임워크와 매우 잘 작동합니다.

Supertest의 주요 특징:

테스트 환경 설정하기

시작하기 전에 기본적인 테스트 환경을 설정해 보겠습니다. Node.js와 npm(또는 yarn)이 설치되어 있다고 가정합니다. 테스트 프레임워크로는 Jest를, API 테스트에는 Supertest를 사용하겠습니다.

  1. Node.js 프로젝트 생성하기:
mkdir api-testing-example
cd api-testing-example
npm init -y
  1. 의존성 설치하기:
npm install --save-dev jest supertest
npm install express  # 또는 API 생성을 위해 선호하는 프레임워크
  1. Jest 설정하기: package.json 파일에 다음을 추가하세요:
{
  "scripts": {
    "test": "jest"
  }
}
  1. 간단한 API 엔드포인트 생성하기: app.js(또는 유사한 이름)라는 파일을 만들고 다음 코드를 추가하세요:
const express = require('express');
const app = express();
const port = 3000;

app.get('/hello', (req, res) => {
  res.send('Hello, World!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

module.exports = app; // 테스트를 위해 내보내기

첫 Supertest 테스트 작성하기

이제 환경 설정이 완료되었으니, API 엔드포인트를 검증하기 위한 간단한 Supertest 테스트를 작성해 보겠습니다. 프로젝트의 루트에 app.test.js(또는 유사한 이름) 파일을 생성하세요:

const request = require('supertest');
const app = require('./app');

describe('GET /hello', () => {
  it('responds with 200 OK and returns "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('Hello, World!');
  });
});

설명:

테스트를 실행하려면 터미널에서 다음 명령을 실행하세요:

npm test

모든 것이 올바르게 설정되었다면 테스트가 통과하는 것을 볼 수 있습니다.

고급 Supertest 기술

Supertest는 고급 API 테스트를 위한 다양한 기능을 제공합니다. 그 중 몇 가지를 살펴보겠습니다.

1. 요청 본문(Body) 보내기

요청 본문에 데이터를 보내려면 .send() 메서드를 사용할 수 있습니다. 예를 들어, JSON 데이터를 받는 엔드포인트를 만들어 봅시다:

app.post('/users', express.json(), (req, res) => {
  const { name, email } = req.body;
  // 데이터베이스에 사용자 생성을 시뮬레이션
  const user = { id: Date.now(), name, email };
  res.status(201).json(user);
});

다음은 Supertest를 사용하여 이 엔드포인트를 테스트하는 방법입니다:

describe('POST /users', () => {
  it('creates a new user', async () => {
    const userData = {
      name: 'John Doe',
      email: 'john.doe@example.com',
    };

    const response = await request(app)
      .post('/users')
      .send(userData)
      .expect(201);

    expect(response.body).toHaveProperty('id');
    expect(response.body.name).toBe(userData.name);
    expect(response.body.email).toBe(userData.email);
  });
});

설명:

2. 헤더(Header) 설정하기

요청에 사용자 정의 헤더를 설정하려면 .set() 메서드를 사용할 수 있습니다. 이는 인증 토큰, 콘텐츠 타입 또는 기타 사용자 정의 헤더를 설정하는 데 유용합니다.

describe('GET /protected', () => {
  it('requires authentication', async () => {
    const response = await request(app).get('/protected').expect(401);
  });

  it('returns 200 OK with a valid token', async () => {
    // 유효한 토큰을 얻는 것을 시뮬레이션
    const token = 'valid-token';

    const response = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(response.text).toBe('Protected Resource');
  });
});

설명:

3. 쿠키(Cookie) 처리하기

Supertest는 쿠키도 처리할 수 있습니다. .set('Cookie', ...) 메서드를 사용하여 쿠키를 설정하거나, .cookies 속성을 사용하여 쿠키에 접근하고 수정할 수 있습니다.

4. 파일 업로드 테스트하기

Supertest는 파일 업로드를 처리하는 API 엔드포인트를 테스트하는 데 사용될 수 있습니다. .attach() 메서드를 사용하여 요청에 파일을 첨부할 수 있습니다.

5. 단언 라이브러리 사용하기 (Chai)

Jest의 내장 단언 라이브러리가 많은 경우에 충분하지만, Supertest와 함께 Chai와 같은 더 강력한 단언 라이브러리를 사용할 수도 있습니다. Chai는 더 표현력 있고 유연한 단언 구문을 제공합니다. Chai를 사용하려면 먼저 설치해야 합니다:

npm install --save-dev chai

그런 다음, 테스트 파일로 Chai를 가져와서 해당 단언을 사용할 수 있습니다:

const request = require('supertest');
const app = require('./app');
const chai = require('chai');
const expect = chai.expect;

describe('GET /hello', () => {
  it('responds with 200 OK and returns "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).to.equal(200);
    expect(response.text).to.equal('Hello, World!');
  });
});

참고: Jest가 Chai와 올바르게 작동하도록 설정해야 할 수도 있습니다. 이는 종종 Chai를 가져와 Jest의 전역 expect와 함께 작동하도록 설정하는 파일을 추가하는 것을 포함합니다.

6. 에이전트(Agent) 재사용하기

특정 환경(예: 인증) 설정이 필요한 테스트의 경우, Supertest 에이전트를 재사용하는 것이 종종 유용합니다. 이렇게 하면 각 테스트 케이스에서 중복된 설정 코드를 피할 수 있습니다.

describe('Authenticated API Tests', () => {
  let agent;

  beforeAll(() => {
    agent = request.agent(app); // 영구적인 에이전트 생성
    // 인증 시뮬레이션
    return agent
      .post('/login')
      .send({ username: 'testuser', password: 'password123' });
  });

  it('can access a protected resource', async () => {
    const response = await agent.get('/protected').expect(200);
    expect(response.text).toBe('Protected Resource');
  });

  it('can perform other actions that require authentication', async () => {
    // 여기서 다른 인증된 작업 수행
  });
});

이 예제에서는 beforeAll 훅에서 Supertest 에이전트를 생성하고 인증합니다. 그러면 describe 블록 내의 후속 테스트들은 각 테스트마다 다시 인증할 필요 없이 이 인증된 에이전트를 재사용할 수 있습니다.

Supertest를 이용한 API 통합 테스트 모범 사례

효과적인 API 통합 테스트를 보장하려면 다음 모범 사례를 고려하십시오:

피해야 할 일반적인 실수

결론

API 통합 테스트는 소프트웨어 개발 프로세스의 필수적인 부분입니다. Supertest를 사용하면 애플리케이션의 품질과 안정성을 보장하는 데 도움이 되는 포괄적이고 신뢰할 수 있는 API 통합 테스트를 쉽게 작성할 수 있습니다. 엔드투엔드 워크플로우 테스트, 현실적인 데이터 사용, 테스트 격리, 테스트 프로세스 자동화에 집중하는 것을 기억하세요. 이러한 모범 사례를 따르면 통합 문제의 위험을 크게 줄이고 더 견고하고 신뢰할 수 있는 제품을 제공할 수 있습니다.

API가 현대 애플리케이션과 마이크로서비스 아키텍처를 계속 주도함에 따라, 견고한 API 테스트, 특히 통합 테스트의 중요성은 계속해서 커질 것입니다. Supertest는 전 세계 개발자들이 API 상호 작용의 신뢰성과 품질을 보장할 수 있도록 강력하고 접근하기 쉬운 도구 모음을 제공합니다.