こんにちは、CX事業本部 Delivery部の若槻です。
以前のエントリで、Vitest の Config のtest.env
で環境変数を設定する方法を紹介しました。
上記方法によりテストファイルやテスト対象モジュール内で参照させる環境変数を設定することができるのですが、注意点として、globalSetup内では Config で設定した環境変数は参照させることはできず、別途設定が必要という制限がありました。
しかし環境変数の設定処理を複数箇所で行うのは避けたいので色々調べてみたところ、環境変数の設定自体も globalSetup 内で行う方法が良さそうだったので紹介します。
試してみた
globalSetup で環境変数を設定する
次のように globalSetup ファイルで環境変数の設定処理を記述します。同ファイルで定義しているsetup
やteardown
でも環境変数を参照する場合は、その手前に記述するようにします。
globalSetup.ts
interface Env {
[key: string]: string;
}
export const env: Env = {
KEY_1: 'DEV_VALUE_1',
KEY_2: 'DEV_VALUE_2',
KEY_3: 'DEV_VALUE_3',
};
Object.keys(env).forEach((key) => {
process.env[key] = env[key];
});
export const setup = (): void => {
console.log('setup', env.KEY_1);
};
export const teardown = (): void => {
console.log('teardown', env.KEY_1);
};
Config では、test.globalSetup
に上記のファイルパスを指定します。
vite.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globalSetup: ['./globalSetup.ts'],
},
});
動作確認のため、テストファイルおよびテスト対象モジュールでも環境変数を参照します。
src/hoge.ts
const KEY_3 = process.env.KEY_3;
export const hogeFunc = () => {
console.log('module', KEY_3);
};
src/hoge.test.ts
import { hogeFunc } from './hoge';
import { test, afterAll } from 'vitest';
const KEY_2_VAL = process.env.KEY_2;
afterAll((): void => {
hogeFunc();
});
test('should pass', (): void => {
console.log('hogeTest', KEY_2_VAL);
});
テストを実行すると、globalSetup、globalTeardown、テストファイル、テスト対象モジュールのそれぞれで環境変数を参照させることができました。
$ npx vitest run
setup DEV_VALUE_1
RUN v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app
stdout | src/hoge.test.ts > should pass
hogeTest DEV_VALUE_2
stdout | unknown test
module DEV_VALUE_3
✓ src/hoge.test.ts (1)
✓ should pass
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 01:02:09
Duration 228ms (transform 26ms, setup 0ms, collect 10ms, tests 1ms, environment 0ms, prepare 47ms)
teardown DEV_VALUE_1
ステージごとに異なる環境変数を設定する
次によくあるパターンとして、development や production などステージごとに異なる環境変数を参照できるようにしてみます。
次のような環境変数を定義するためのファイルを別途作成して、ステージごとの環境変数のオブジェクトを定義します。
environment.ts
interface Env {
[key: string]: string;
}
export const developmentEnv: Env = {
KEY_1: 'DEV_VALUE_1',
KEY_2: 'DEV_VALUE_2',
KEY_3: 'DEV_VALUE_3',
};
export const productionEnv: Env = {
KEY_1: 'PRD_VALUE_1',
KEY_2: 'PRD_VALUE_2',
KEY_3: 'PRD_VALUE_3',
};
globalSetup で上述のファイルを読み込み、TEST_MODE
で指定したステージの環境変数を設定します。
globalSetup.ts
import { developmentEnv, productionEnv } from 'environment';
const TEST_MODE = process.env.TEST_MODE || 'development';
const env = TEST_MODE === 'production' ? productionEnv : developmentEnv;
Object.keys(env).forEach((key) => {
process.env[key] = env[key];
});
export const setup = (): void => {
console.log('setup', env.KEY_1);
};
export const teardown = (): void => {
console.log('teardown', env.KEY_1);
};
npm scripts でそれぞれのステージのTEST_MODE
を指定するスクリプトを定義します。
package.json
{
"scripts": {
"test:dev": "TEST_MODE=development vitest run",
"test:prd": "TEST_MODE=production vitest run"
},
}
それぞれ実行すると、ステージごとに異なる環境変数を参照できることが確認できました。
- development
$ npm run test:dev
> cdk_sample_app@0.1.0 test:dev
> TEST_MODE=development vitest run
setup DEV_VALUE_1
RUN v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app
stdout | src/hoge.test.ts > should pass
hogeTest DEV_VALUE_2
stdout | unknown test
module DEV_VALUE_3
✓ src/hoge.test.ts (1)
✓ should pass
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 01:05:20
Duration 242ms (transform 34ms, setup 0ms, collect 11ms, tests 3ms, environment 0ms, prepare 58ms)
teardown DEV_VALUE_1
- production
$ npm run test:prd
> cdk_sample_app@0.1.0 test:prd
> TEST_MODE=production vitest run
setup PRD_VALUE_1
RUN v0.34.4 /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app
stdout | src/hoge.test.ts > should pass
hogeTest PRD_VALUE_2
stdout | unknown test
module PRD_VALUE_3
✓ src/hoge.test.ts (1)
✓ should pass
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 01:06:05
Duration 246ms (transform 37ms, setup 0ms, collect 9ms, tests 1ms, environment 0ms, prepare 54ms)
teardown PRD_VALUE_1
おわりに
Vitest でのテスト実行時に参照させたい環境変数の設定は globalSetup を利用すると便利だという話でした。
設定処理の重複を避けることができますし、環境変数をオブジェクトで定義するので.env
ファイルで管理するのに比べて幾分扱いやすくなります。dotenvなどのパッケージを別途導入する必要もありません。
Vitest を利用する上での参考になれば幸いです。
以上