Vitest で globalSetup および globalTeardown を構成する

2023/09/11 追記
2023.09.11

こんにちは、CX 事業本部 Delivery 部の若槻です。

Jest では globalSetupglobalTeardown を構成することで、すべてのテストスイートの実行前後に任意の処理を実行することができます。

今回は、この globalSetup および globalTeardown を、オルト Jest なテスティングフレームワークである Vitest で行う方法を確認してみました。

やってみた

結論としては、Vitest では Config で globalSetup は構成できましたが、globalTeardown に関してはオプションが無く、Config 以外の方法で別途構成する必要がありました。

globalSetup

test.globalSetupで前処理を定義したファイルを指定します。

vite.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globalSetup: './globalSetup.ts',
  },
});

指定されたファイル側では実行したい処理の関数を default export します。

globalSetup.ts

const setUp = (): void => {
  console.log('Global Setup was called.');
};

export default setUp;

実行すると、すべてのテストスイートの実行前に globalSetup.ts で定義した関数が 1 回実行されます。

$ npm run test

> cdk_sample_app@0.1.0 test
> vitest run

Global Setup was called.

 RUN  v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app

 ✓ src/hoge.test.ts (1)
 ✓ src/fuga.test.ts (1)

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  01:08:06
   Duration  213ms (transform 25ms, setup 0ms, collect 15ms, tests 3ms, environment 0ms, prepare 89ms)

複数の globalSetup を実行したい場合

複数の globalSetup を実行したい場合は、ファイル名を配列で指定します。

vite.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globalSetup: ['./globalSetup.ts', './globalSetup.ts'],
  },
});

テストを実行すると、globalSetup.ts で定義した関数が 2 回実行されました。

$ npm run test

> cdk_sample_app@0.1.0 test
> vitest run

Global Setup was called.
Global Setup was called.

 RUN  v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app

 ✓ src/fuga.test.ts (1)
 ✓ src/hoge.test.ts (1)

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  01:12:35
   Duration  208ms (transform 24ms, setup 0ms, collect 14ms, tests 3ms, environment 0ms, prepare 87ms)

test.env で指定した環境変数は globalSetup で使用されない

globalSetup の中で環境変数を使用したい場合は、Config の中で指定できるのでしょうか。

globalSetupと合わせて、test.envで環境変数を設定します。これは以前のエントリで紹介した方法です。

vite.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    env: {
      ENV_KEY_1: 'ENV_VALUE_1',
    },
    globalSetup: './globalSetup.ts',
  },
});

globalSetup の関数内で環境変数を参照してみます。

globalSetup.ts

const setUp = (): void => {
  const ENV_VALUE_1 = process.env.ENV_KEY_1;

  console.log(ENV_VALUE_1);
};

export default setUp;

テストを実行すると、環境変数の値が undefined となってしまいました。どうやら globalSetup で環境変数を使用したい場合は、別途外部から注入する必要があるようです。

$ npm run test

> cdk_sample_app@0.1.0 test
> vitest run

undefined

 RUN  v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app

 ✓ src/fuga.test.ts (1)
 ✓ src/hoge.test.ts (1)

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  01:45:03
   Duration  263ms (transform 22ms, setup 0ms, collect 16ms, tests 2ms, environment 0ms, prepare 105ms)

globalTeardown

さて、前述の globalSetup があるなら globalTeardown もありそうなのですが、Vitest Config にはそのようなオプションはありませんでした。Jest のようにセットで実装があるものと思っていたのでこれは予想外でした。

2023/09/11 追記:Config を使って globalTeardown を構成する方法が分かったので記載します。

次のようにteardownという named export で定義された関数は globalTeardown となります。setupの場合は globalSetup となります。

globalSetup.ts

export const setup = (): void => {
  console.log('Global Setup was called.');
};

export const teardown = (): void => {
  console.log('Global Teardown was called.');
};

Config の記載です。

vite.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globalSetup: './globalSetup.ts',
  },
});

テストを実行すると、すべてのテストの実行後に globalTeardown を実行させることができました。

$ npx vitest run
Global Setup was called.

 RUN  v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app

 ✓ src/fuga.test.ts (1)
 ✓ src/hoge.test.ts (1)

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  22:35:45
   Duration  201ms (transform 21ms, setup 0ms, collect 16ms, tests 2ms, environment 0ms, prepare 90ms)

Global Teardown was called.

ちなみに、default export で定義した関数は必ず globalSetup となり、テストの実行前に実行されます。globalTeardown は named export のみ対応しているようです。

以前紹介していた方法はこちら

よって、Config 以外の方法で別途構成する必要がありました。ここでは、例として npm script で globalTeardown を構成してみます。

npm script を次のように記述します。test:with-teardownを実行すれば、Vitest のテスト実行の後に globalTeardown を別途実行するようにします。

package.json

{
  "scripts": {
    "test:with-teardown": "npm run test && npm run teardown",
    "test": "vitest run",
    "teardown": "npx ts-node globalTearDown.ts"
  }
}

tearDown の処理の記述です。モジュールを実行したら処理が実行されます。

globalTearDown.ts

const tearDown = (): void => {
  console.log('Global Teardown was called.');
};

tearDown();

test:with-teardownを実行すると、Vitest のテスト実行の後に globalTeardown が実行されました。

$ npm run test:with-teardown

> cdk_sample_app@0.1.0 test:with-teardown
> npm run test && npm run teardown


> cdk_sample_app@0.1.0 test
> vitest run

Global Setup was called.

 RUN  v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app

 ✓ src/fuga.test.ts (1)
 ✓ src/hoge.test.ts (1)

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  01:57:04
   Duration  223ms (transform 19ms, setup 0ms, collect 15ms, tests 2ms, environment 0ms, prepare 87ms)


> cdk_sample_app@0.1.0 teardown
> npx ts-node globalTearDown.ts

Global Teardown was called.

スマートな方法ではないかも知れませんが、globalTeardown を構成することができました。

おわりに

Vitest で globalSetup および globalTeardown を構成する方法を確認してみました。

繰り返しますが、globalTeardown のオプションが Vitest の Config で未実装なのは予想外でした。vitest-dev/vitestの Pull Request や Issue を漁ってみましたが、実装の予定や提案は見つかりませんでした。私の見逃しでしょうか。もし Config を使用した実装方法があれば教えていただけると嬉しいです。 見つかりました。私の探し方がよくありませんでした。これで Vitest をより便利に使うことができそうです。

以上