4 ポイント 投稿者 GN⁺ 2024-04-08 | 1件のコメント | WhatsAppで共有

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-postgresnpm では 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 はブラウザ環境を完全にサポートする。
  • Web アプリは TCP ポートを listen できないが、PostgresMock.createSocketnode-postgres の設定を利用できる。
  • バンドラが静的 import を解析する場合、欠けている(オプションの)Node.js モジュールのため、デフォルト設定で警告が表示されることがある。
  • ブラウザでデータベースだけを動かしたい場合は pglite も検討できるが、機能は限定的。
  • pgmock は、テスト環境で求められる本番 PostgreSQL 環境と機能的に同等であることを目指して設計されている。

仕組み

  • WebAssembly 上で Postgres を動かす方法は 2 つある。WASM をネイティブにサポートするようにフォークする方法と、x86 エミュレータ上で Postgres サーバーをエミュレートする方法だ。
  • 前者は性能が高くメモリ使用量も少ないが、シングルユーザーモード(接続なし)しか使えず、拡張機能もサポートしない。
  • テストと本番の差異を避けたく、またテストでは性能が主な関心事ではないため、pgmock は現在後者のアプローチを採用している。
  • 中期的には、ネイティブな Postgres WASM フォークが成熟すれば両方の選択肢を提供し、最終的にはデフォルトでネイティブ WASM に切り替える計画。
  • PostgresMock.subtle 内の API を除けば、大きな変更はあまり発生しない見込み。
  • pgmock は、実際のネットワークのように振る舞う JavaScript 内のネットワークスタックをシミュレートすることで、ローレベルソケットへのアクセスを許可しないプラットフォームでも TCP 接続を再現できるようにし、ネットワークプロキシに依存せず JavaScript ランタイム内だけで完全な機能互換性を提供する。

コントリビュートしたいですか?

  • 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 などがあり、それぞれ Docker コンテナを使う統合テストや Java アプリケーション向けのインメモリデータベースを提供している。

1件のコメント

 
GN⁺ 2024-04-08
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クライアントと一緒に使う方法があるかという質問。