GN⁺: HN 공개: 업무 중 구축한 인메모리 PostgreSQL을 E2E 테스트를 위해 오픈 소스화
(github.com/stackframe-projects)pgmock
데모 — Discord
-
pgmock
은 단위 및 E2E 테스트를 위한 메모리 내 PostgreSQL 모의 서버임. - 외부 의존성이 없으며 Node.js와 브라우저 모두에서 WebAssembly 내에서 전적으로 실행됨.
설치
-
npm install pgmock
명령어를 통해 설치 가능. - 브라우저에서
pgmock
을 실행하고자 한다면, 브라우저 지원 섹션의 자세한 지침을 참조할 것.
시작하기
- 메모리 내 서버를 다음과 같이 실행할 수 있음:
import { PostgresMock } from "pgmock"; const mock = await PostgresMock.create(); const connectionString = await mock.listen(5432);
-
node-postgres
(npm
에서pg
)를 사용하는 경우, 포트를 사용하지 않고 브라우저에서도 작동하는 구성 객체를 제공함:import * as pg from "pg"; const mock = await PostgresMock.create(); const client = new pg.Client(mock.getNodePostgresConfig()); await client.connect(); console.log(await client.query('SELECT $1::text as message', ['Hello world!']));
- 사용 후 자원을 해제하기 위해 모의 서버를 파괴하는 것이 좋은 관행임:
mock.destroy();
문서화
- 사용 가능한 모든 메소드와 그 문서화에 대한 목록은 PostgresMock 소스 파일을 확인할 것.
브라우저 지원
-
pgmock
은 브라우저 환경을 완전히 지원함. - 웹앱은 TCP 포트를 수신할 수 없지만,
PostgresMock.createSocket
과node-postgres
구성을 사용할 수 있음. - 번들러가 정적으로 가져오기를 분석하는 경우, 누락된 (선택적인) Node.js 모듈 때문에 기본 구성에 경고가 표시될 수 있음.
- 브라우저에서 데이터베이스만 실행하려는 경우,
pglite
를 고려할 수 있으나, 이는 기능이 제한적임. -
pgmock
은 테스트 환경에서 원하는 생산 PostgreSQL 환경과 기능적으로 동등함을 목표로 설계됨.
작동 원리
- WebAssembly에서 Postgres를 실행하는 두 가지 접근 방식이 있음: WASM을 원래 지원하도록 포크하거나 x86 에뮬레이터에서 Postgres 서버를 에뮬레이션함.
- 전자는 성능이 더 뛰어나고 메모리 사용량이 적지만, 단일 사용자 모드(연결 없음)와 확장 기능을 지원하지 않음.
- 테스트와 생산 간의 차이를 방지하고 테스트에서 성능이 주요 관심사가 아니기 때문에,
pgmock
은 현재 후자의 접근 방식을 사용함. - 중기적으로는, 원래 Postgres WASM 포크가 성숙하면 두 옵션을 모두 제공하고, 결국 기본적으로 원래 WASM으로 전환할 계획임.
-
PostgresMock.subtle
내의 API를 제외하고는 많은 변경 사항이 발생하지 않을 것으로 예상됨. -
pgmock
은 실제 네트워크처럼 행동하는 자바스크립트 내 네트워크 스택을 시뮬레이션하여, 원시 소켓 액세스를 허용하지 않는 플랫폼에서도 TCP 연결을 시뮬레이션할 수 있도록 함으로써, 네트워크 프록시에 의존하지 않고 전적으로 자바스크립트 런타임 내에서 전체 기능 호환성을 제공함.
기여하고 싶으신가요?
- Discord 서버에서 우리와 대화할 수 있음.
다른 Docker 이미지나 데이터베이스를 실행할 수 있나요?
- 이론적으로 가능함. 관심이 있다면 Discord 서버에서 연락할 것.
감사의 말
- 이를 가능하게 하는 x86 에뮬레이터인 v86에 감사.
- WebAssembly 내에서 Postgres를 실행하는 자체 접근 방식을 구축한 Supabase & Snaplet에 감사.
-
pgmock
을 구축하는 동안 급여를 지급한 Stackframe에 감사.
GN⁺의 의견
-
pgmock
은 개발자들이 PostgreSQL 데이터베이스와의 상호작용을 테스트할 때 유용한 도구임. 실제 데이터베이스 서버를 설정하고 관리하는 번거로움 없이, 코드의 데이터베이스 상호작용을 검증할 수 있음. - 이러한 도구는 테스트 주도 개발(TDD)이나 지속적 통합(CI) 환경에서 매우 유용함. 개발자들은 빠르게 테스트를 실행하고, 코드 변경에 따른 영향을 즉시 확인할 수 있음.
-
pgmock
은 WebAssembly를 사용하여 브라우저와 Node.js 환경 모두에서 작동하므로, 다양한 개발 환경에서의 호환성을 제공함. 이는 프론트엔드와 백엔드 개발자 모두에게 이점을 제공함. - 그러나
pgmock
이 실제 PostgreSQL 서버의 모든 기능을 완벽하게 에뮬레이션할 수 있는지, 특히 성능과 확장 기능 측면에서는 의문이 남음. 실제 데이터베이스 환경과의 차이가 테스트 결과에 영향을 미칠 수 있음. - 비슷한 기능을 제공하는 다른 프로젝트로는 Testcontainers, H2 Database 등이 있으며, 이들은 각각 도커 컨테이너를 사용하는 통합 테스트와 자바 애플리케이션을 위한 인메모리 데이터베이스를 제공함.
Hacker News 의견
-
pgmock 소개
- 한 개발자가 몇 달 동안 Postgres의 인메모리 버전을 개발함.
- 이 버전은 기존 데이터베이스와 기능적으로 동등함.
- 외부 프로세스나 프록시가 필요 없으며, WASM을 실행할 수 있는 플랫폼(Node.js, 브라우저 등)에서 작동함.
- JavaScript 객체를 생성하는 것처럼 간단하게 새 데이터베이스와 모의 데이터를 생성할 수 있음.
- pglite와는 다르게, pgmock은 원본 Postgres를 내부에 포함한 x86 에뮬레이터를 실행함. pglite는 Postgres 포크를 직접 WASM으로 컴파일하여 더 빠르고 가벼우나, 단일 사용자 모드와 몇몇 확장 기능만 지원하여 일반 Postgres 클라이언트로 연결할 수 없음.
- 이론적으로는 어떤 Docker 이미지도 WebAssembly 플랫폼에서 실행 가능하게 수정할 수 있음.
-
RAM 디스크에서 Postgres 실행에 대한 질문
- Postgres를 RAM 디스크에서 실행하는 것과 비교하여, 브라우저/Node 환경에서 실행 가능하고 테스트에 의해 생성/업데이트/파괴될 수 있는 이점에 대해 설명해달라는 요청.
-
실제 서버 대신 인메모리 서버 사용 경험 공유
- 과거에 다양한 (맞춤형) 가짜 인메모리 서버를 테스트에 사용했으나, 현재는 Testcontainers를 사용하여 실제 서비스를 실행함.
-
프로젝트의 지적 재산권에 대한 질문
- 제목에서 "내가 직장에서 만들었다"는 표현이 지적 재산권이 고용주에게 속하는 것을 의미하는지, 그리고 직장의 자원을 사용했다면 오픈소스로 공개하는 것이 허용되는지에 대한 의문 제기.
-
개발 환경 복제에 대한 조언
- 생산 데이터를 덤프하고, 민감한 데이터를 제거하고, 로그 테이블 같은 불필요한 테이블을 줄여서 개발 복사본을 만들 것을 권장. 이를 개발, QA, E2E 등에 복제함으로써 E2E 테스트에 필요한 확장, 트리거, 함수, 뷰, 인덱스, 데이터를 확보할 수 있음.
-
pgmock 개발 배경과 CI 통합에 대한 질문
- 이 프로젝트를 개발하게 된 동기와 Docker 컨테이너에서 Postgres를 실행하는 것이 너무 느렸는지에 대한 질문.
- pgmock을 통합하기 전후의 CI 설정과 E2E 테스트 흐름에 대한 설명 요청.
- 이 솔루션으로의 이전이 어려웠는지에 대한 질문.
-
H2 데이터베이스와의 비교 질문
- Postgres 호환 모드에서 H2 데이터베이스와 pgmock을 비교하는 질문.
-
pgmem 사용 경험 공유
- pgmem을 사용하여 비슷한 목적으로 지난 몇 년간 작업한 경험 공유.
-
ORM 지원에 대한 질문
- Sequelize, Prisma, Drizzle 같은 ORM을 테스트에 사용할 수 있는지에 대한 질문.
-
Prisma 클라이언트와의 사용 가능성에 대한 질문
- Prisma 클라이언트와 함께 사용할 수 있는 방법에 대한 질문.