📷

Node.js Test RunnerのSnapshot testをTypeScript環境でも使う

2025/03/20に公開

Node.js 22から、組み込みのTest RunnerだけでSnapshot testができるようになりました

https://nodejs.org/ja/learn/test-runner/using-test-runner#snapshot-tests

OpenHands🙌に開発をさせるとき、lintやテストのエラーを自動で修正してくれるため、Snapshot testと相性が良さそうです

Reactコンポーネントのテスト例

以下のようなテストを、Node.jsとreact-domだけで書けます

import { describe, it } from "node:test";

import { renderToStaticMarkup } from "react-dom/server";

import "../setup-test.js";
import { Button } from "./button.js";

describe("Button", () => {
  it("表示される", (t) => {
    t.assert.snapshot(renderToStaticMarkup(<Button>テストボタン</Button>));
  });

  it("primary variantが表示される", (t) => {
    t.assert.snapshot(
      renderToStaticMarkup(<Button variant="primary">テストボタン</Button>),
    );
  });

  it("子要素が正しく表示される", (t) => {
    t.assert.snapshot(
      renderToStaticMarkup(
        <Button>
          <span>アイコン</span>
          <span>テキスト</span>
        </Button>,
      ),
    );
  });
});

スナップショットはnode --test --test-update-snapshotsで更新でき、以下のような形式で保存されます

exports[`Button > 表示される 1`] = `
"<button type=\\"button\\" class=\\"inline-flex justify-center shadow-xs focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 bg-white text-gray-900 font-normal hover:bg-gray-50 focus-visible:outline-gray-300 px-3 py-2 rounded-md text-sm\\">テストボタン</button>"
`;

TypeScript環境でのスナップショットの保存場所を調整する

TypeScriptを使用している環境では、srcディレクトリのコードをtscでdistディレクトリにコンパイルさせたりします
Node.js Test RunnerはdistにあるJavaScriptに対して実行されるため、スナップショットもGit管理対象外であるdist内に作成されます

これを防ぐには、snapshot.setResolveSnapshotPathを使用して、スナップショットの保存場所をsrcに調整する必要があります

setup-test.tsのようなファイルを用意して、テストのセットアップをします

import path from "node:path";
import { snapshot } from "node:test";

snapshot.setResolveSnapshotPath((testFilePath) => {
  if (!testFilePath) {
    throw new Error("testFilePath is required");
  }

  const srcPath = testFilePath.replace(
    path.resolve("dist"),
    path.resolve("src"),
  );

  return path.join(
    path.dirname(srcPath),
    `${path.basename(srcPath, path.extname(srcPath))}.snapshot.cjs`,
  );
});

各テストファイルにて以下のように読み込めば、スナップショットがsrc内に作成されるようになります

import "../setup-test.js";

これで無事TypeScript環境でも、Snapshot testができるようになります

Discussion