Testcontainers for Node.js 시작하기
Testcontainers for Node.js 시작하기
이 가이드에서는 Testcontainers for Node.js를 이용해 실제 PostgreSQL 인스턴스로 Node.js 애플리케이션을 만들고 데이터베이스 상호작용을 테스트하는 방법을 배워요.
출처: 문서
본문
이 가이드를 통해 다음 내용을 배울 수 있어요.
- PostgreSQL에서 고객을 저장하고 조회하는 Node.js 애플리케이션 만들기
- Testcontainers와 Jest로 통합 테스트 작성하기
- Docker 컨테이너의 실제 PostgreSQL 데이터베이스에 대해 테스트 실행하기
사전 준비 (Prerequisites)
- Node.js 18 이상
- npm
- Testcontainers가 지원하는 Docker 환경
참고: Testcontainers가 처음이라면 Testcontainers 개요를 방문해 알아보는 걸 권장해요.
Node.js 프로젝트 만들기
새 Node.js 프로젝트를 만들어요.
$ npm init -y
pg, jest, @testcontainers/postgresql을 의존성으로 추가해요.
$ npm install pg --save
$ npm install jest @testcontainers/postgresql --save-dev
고객 리포지토리 구현하기
PostgreSQL에서 고객을 관리하는 함수를 가진 src/customer-repository.js를 만들어요.
async function createCustomerTable(client) {
const sql =
"CREATE TABLE IF NOT EXISTS customers (id INT NOT NULL, name VARCHAR NOT NULL, PRIMARY KEY (id))";
await client.query(sql);
}
async function createCustomer(client, customer) {
const sql = "INSERT INTO customers (id, name) VALUES($1, $2)";
await client.query(sql, [customer.id, customer.name]);
}
async function getCustomers(client) {
const sql = "SELECT * FROM customers";
const result = await client.query(sql);
return result.rows;
}
module.exports = { createCustomerTable, createCustomer, getCustomers };
이 모듈은 세 가지 함수를 제공해요.
createCustomerTable()은customers테이블이 없으면 만들어요.createCustomer()는 고객 레코드를 삽입해요.getCustomers()는 모든 고객 레코드를 가져와요.
Testcontainers로 테스트 작성하기
테스트와 함께 src/customer-repository.test.js를 만들어요.
const { Client } = require("pg");
const { PostgreSqlContainer } = require("@testcontainers/postgresql");
const {
createCustomerTable,
createCustomer,
getCustomers,
} = require("./customer-repository");
describe("Customer Repository", () => {
jest.setTimeout(60000);
let postgresContainer;
let postgresClient;
beforeAll(async () => {
postgresContainer = await new PostgreSqlContainer().start();
postgresClient = new Client({
connectionString: postgresContainer.getConnectionUri(),
});
await postgresClient.connect();
await createCustomerTable(postgresClient);
});
afterAll(async () => {
await postgresClient.end();
await postgresContainer.stop();
});
it("should create and return multiple customers", async () => {
const customer1 = { id: 1, name: "John Doe" };
const customer2 = { id: 2, name: "Jane Doe" };
await createCustomer(postgresClient, customer1);
await createCustomer(postgresClient, customer2);
const customers = await getCustomers(postgresClient);
expect(customers).toEqual([customer1, customer2]);
});
});
테스트가 하는 일을 살펴보면,
beforeAll블록이PostgreSqlContainer로 실제 PostgreSQL 컨테이너를 시작해요.- 그런 다음 컨테이너에 연결된
pg클라이언트를 만들고customers테이블을 설정해요. afterAll블록이 클라이언트 연결을 닫고 컨테이너를 중지해요.- 테스트는 고객 두 명을 삽입하고 모든 고객을 가져와 결과가 일치하는지 단언해요.
- 테스트 타임아웃을 60초로 설정해서 첫 실행(Docker 이미지를 받아야 할 때)에 컨테이너가 시작될 시간을 확보해요.
테스트 실행과 다음 단계
package.json에 아직 없다면 테스트 스크립트를 추가해요.
{
"scripts": {
"test": "jest"
}
}
그런 다음 테스트를 실행해요.
$ npm test
다음과 같은 출력이 보여야 해요.
PASS src/customer-repository.test.js
Customer Repository
✓ should create and return multiple customers (5 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Testcontainers가 내부적으로 무엇을 하는지 — 어떤 컨테이너를 시작하고, 어떤 버전을 사용하는지 — 보려면 DEBUG 환경 변수를 설정해요.
$ DEBUG=testcontainers* npm test
요약 (Summary)
Testcontainers for Node.js 라이브러리는 목(mock) 대신 프로덕션에서 쓰는 것과 같은 종류의 데이터베이스(Postgres)를 사용해 통합 테스트를 작성할 수 있게 도와줘요. 목을 쓰지 않고 실제 서비스와 대화하기 때문에, 코드를 리팩터링해도 애플리케이션이 예상대로 동작하는지 검증할 수 있답니다.
PostgreSQL 외에도 Testcontainers는 많은 SQL 데이터베이스, NoSQL 데이터베이스, 메시징 큐 등을 위한 전용 모듈을 제공해요.
Testcontainers에 대해 더 알아보고 싶다면 Testcontainers 개요를 방문해요.
더 읽어보기 (Further reading)
- Testcontainers for Node.js 문서