Node.jsガイド
@osmem/coreはosmem-serverを子プロセスとして起動し、アドレスが報告されるとテストにクローンのURLを渡します。npmがoptional dependenciesから対応するplatform package(@osmem/darwin-arm64、@osmem/linux-x64など)もinstallするため、binaryを別途設定する必要はありません。このページでは、VitestとJest、素のnode:test、そしてオプションを扱います。
インストール
Section titled “インストール”npm install --save-dev @osmem/core @opensearch-project/opensearch@osmem/coreはローカルサーバーとテスト用helperを提供し、@opensearch-project/opensearchはアプリ側と同じ公式クライアントです。npmが現在のOSとCPUに合うoptional binary packageを選びます。
起動し、schemaを登録して検索する
Section titled “起動し、schemaを登録して検索する”launcherは子プロセスを1つ起動します。requestでindexを作ってdocumentを登録し、同じserver URLを公式クライアントに渡します。
import { OsmemServer } from "@osmem/core";import { Client } from "@opensearch-project/opensearch";
const server = await OsmemServer.start({ japanese: false });try { await server.request("PUT", "/products", { mappings: { properties: { name: { type: "text", fields: { keyword: { type: "keyword" } } } } }, }); await server.request("PUT", "/products/_doc/1", { name: "Red Apple" });
const client = new Client({ node: server.url }); const result = await client.search({ index: "products", body: { query: { match: { name: "apple" } } } }); console.log(result.body.hits.hits);} finally { await server.close();}fixtureが大きくなったらstartにseed directoryを渡します。共通seed形式ならmappingやdocumentをレビューしやすく、言語間でも共有できます。
ファイルごとに1サーバー、状態を変えるテストはclone
Section titled “ファイルごとに1サーバー、状態を変えるテストはclone”beforeAllでサーバーを起動し、afterAllで閉じます。withCloneはクローンを作り、それを渡して関数を実行し、終わったらクローンを削除します。
documentの追加・削除、mappingの変更、indexの作成・削除など、indexの状態を変えるテストではcloneを使います。検索だけを行うテストなら、server.urlを直接使えます。
import { OsmemServer } from "@osmem/core";import { Client } from "@opensearch-project/opensearch";
let server;beforeAll(async () => { server = await OsmemServer.start({ seed: ["./testdata/seed"], freeze: true });});afterAll(() => server.close());
test("adds a product", async () => { await server.withClone(async (clone) => { const client = new Client({ node: clone.url }); await client.index({ index: "products", id: "x", body: { name: "new" } }); const res = await client.get({ index: "products", id: "x" }); expect(res.body.found).toBe(true); });});同じコードがJestでもVitestでも動きます。node:testでは、beforeAll/afterAllの代わりにnode:testのbefore/afterを使います。
自分で閉じたい場合は、server.clone()がクローンのオブジェクトを返します。clone.urlが、どのOpenSearchクライアントにも渡せるアドレスです。読み取りだけのテストはserver.urlを直接使えます。
OsmemServer.start(options)が受け付けるもの:
| オプション | 意味 |
|---|---|
seed |
シードディレクトリか.ndjsonファイル、またはその配列。指定順に読み込む(形式) |
freeze |
ベースへの書き込みを即座に拒否する(指定しなければ最初のクローンで凍結される) |
japanese |
falseでkuromojiを無効にする。デフォルトはtrue |
addr |
listenするアドレス。デフォルトは127.0.0.1:0 |
binary |
osmem-serverのパス。プラットフォームパッケージより優先される |
startupTimeoutMs |
デフォルトは30000 |
inheritStderr |
falseでサーバーの標準エラーを表示しない |
server.request(method, path, body)は任意のJSONリクエストをベースに送り、エラーステータスなら例外を投げます。/_osmemや_countに対するアサーションに便利です。
環境変数OSMEM_SERVER_BINは、プラットフォームパッケージより優先されます。ローカルでビルドしたサーバーで試すときに使います。
CommonJS
Section titled “CommonJS”require("@osmem/core")は、同じstartメソッドを持つ{ OsmemServer }を返します。実装はESモジュールとして遅延ロードされるので、startはいつもどおりawaitしてください。
プロセスのライフタイム
Section titled “プロセスのライフタイム”子プロセスには--parent-pidと、パイプでつないだ標準入力が渡されます。終了するのは、テストプロセスが終わって標準入力が閉じたとき、親のpidが消えたとき、あるいはserver.close()が呼ばれたときです。close()は標準入力を閉じ、5秒経っても終わらなければプロセスをkillします。テストランナーがクラッシュしても、サーバーは残りません。
テストのライフタイムを選ぶ
Section titled “テストのライフタイムを選ぶ”- テストごとに新しいserver: 各テスト内で
OsmemServer.start({ seed })を呼び、finallyで閉じます。境界は単純ですが、起動とseedを繰り返します。 - fileまたはworkerごとに1つのserver: 上の例のように
beforeAllで起動し、afterAllで閉じます。読み取り専用テストはserver.urlを直接使えます。 - 副作用のあるテスト: document、mapping、indexの状態を変えるなら、
server.withClone(...)かserver.clone()でseed済みbaseをforkします。cloneは隔離され、閉じれば変更は破棄されます。withCloneならassertionが失敗しても後始末されます。
書き込み可能なcloneをテスト間で共有しないでください。並列テストでは、それぞれ専用cloneを作ります。