アレについて記す

Angularマルチプロジェクト構成のアプリケーションのテストライブラリをJestに変更する

Posted on February 03, 2020 at 21:00 (JST)

Angularマルチプロジェクト構成のアプリケーションのテストライブラリをJestに変更する方法をメモとして残す。

サンプルリポジトリ: angular-storyshots-sample/multiple-projects-app (変更点)

動作環境

OS: macOS Mojave ver. 10.14.6
Node: v12.14.0
@angular/cli: 9.0.0-rc.10
jest-preset-angular: 8.0.0

概要

@briebug/jest-schematicは2020/02/03現在マルチプロジェクト構成のアプリケーションには対応していないため、Jest導入には下記の作業が必要となる。

  1. Jest関連ライブラリのインストール
  2. Karma関連ファイルの削除
  3. Jest用設定の追加・変更
  4. package.jsonへテスト起動script追加

1. Jest関連ライブラリのインストール

下記コマンド実行によりライブラリのインストールが完了する。
ルートディレクトリ直下にsrcディレクトリが追加されjest設定用のjsが追加されるが、後ほど移動する。
変更差分

ng add @briebug/jest-schematic

2. Karma関連ファイルの削除

  • projects/*/karma.conf.jsを削除
  • projects/*/src/test.tsを削除
  • projects/*/tsconfig.spec.jsonからtest.jsへの参照記述を削除
-  "files": [
-    "src/test.ts"
-  ],
+  "files": [],

3. Jest用設定の追加・変更

project単位でテスト実行するための設定を下記の順に行う。

  1. package.jsonからjest用設定を削除
  2. projects/*/tsconfig.spec.jsonのコンパイルオプション追加
  3. root/src下のリソースをprojects/*/src下へ移動
  4. jestの共通設定をprojects/jest.base.config.jsに記述
  5. 各プロジェクト固有のjest設定をprojects/*/jest.config.jsに記述

変更差分

3-1. package.jsonからjest用設定を削除

手順1でpackage.jsonにjest設定が追加されるが、この設定はマルチプロジェクト構成用ではないので削除する。

-  "jest": {
-    "preset": "jest-preset-angular",
-    "roots": [
-    ...
-  }

3-2. projects/*/tsconfig.spec.jsonのコンパイルオプション追加

テスト用のコンパイルオプションを追加する。

    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "allowJs": true,
    "esModuleInterop": true

3-3. root/src下のリソースをprojects/*/src下へ移動

root/srcからsetup-jest.tstest-config.helper.tsを各src下へ移動する。

[projects/*/src/setup-jest.ts]

import 'jest-preset-angular';

/* global mocks for jsdom */
const mock = () => {
  let storage: { [key: string]: string } = {};
  return {
    getItem: (key: string) => (key in storage ? storage[key] : null),
    setItem: (key: string, value: string) => (storage[key] = value || ''),
    removeItem: (key: string) => delete storage[key],
    clear: () => (storage = {})
  };
};

Object.defineProperty(window, 'localStorage', { value: mock() });
Object.defineProperty(window, 'sessionStorage', { value: mock() });
Object.defineProperty(window, 'getComputedStyle', {
  value: () => ['-webkit-appearance'],
});

Object.defineProperty(document.body.style, 'transform', {
  value: () => {
    return {
      enumerable: true,
      configurable: true,
    };
  },
});

/* output shorter and more meaningful Zone error stack traces */
// Error.stackTraceLimit = 2;

[projects/*/src/test-config.helper.ts]

import {TestBed} from '@angular/core/testing';

type CompilerOptions = Partial<{
  providers: any[];
  useJit: boolean;
  preserveWhitespaces: boolean;
}>;
export type ConfigureFn = (testBed: typeof TestBed) => void;

export const configureTests = (
  configure: ConfigureFn,
  compilerOptions: CompilerOptions = {}
) => {
  const compilerConfig: CompilerOptions = {
    preserveWhitespaces: false,
    ...compilerOptions,
  };

  const configuredTestBed = TestBed.configureCompiler(compilerConfig);

  configure(configuredTestBed);

  return configuredTestBed.compileComponents().then(() => configuredTestBed);
};

3-4. jestの共通設定をprojects/jest.base.config.jsに記述

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['<rootDir>/src'],
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest'
  },
  globals: {
    'ts-jest': {
      tsConfig: '<rootDir>/tsconfig.spec.json',
      stringifyContentPathRegex: '\\.html$',
      astTransformers: [
        'jest-preset-angular/build/InlineFilesTransformer',
        'jest-preset-angular/build/StripStylesTransformer'
      ]
    }
  }
};

3-5. 各プロジェクト固有のjest設定をprojects/*/jest.config.jsに記述

現状プロジェクト固有設定は無いため、すべて下記の内容となる。
★ テスト実行時にこれらのファイルを指定して起動するため、各プロジェクトごとに用意した。

const baseConfig = require('../jest.base.config');

module.exports = {
  ...baseConfig,
};

4. package.jsonへテスト起動script追加

Jest用設定は以下いずれかで指定できる。

  • --configオプションで設定ファイルをパス指定
  • package.jsonにjest設定があれば自動読み込み
  • root/jest.config.jsファイルがあれば自動読み込み

各プロジェクト毎に起動するために当該プロジェクトのconfigをパス指定する。

"test": "npm run test:common && npm run test:admin && npm run test:customer",
"test:admin": "jest --config=projects/admin/jest.config.js",
"test:customer": "jest --config=./projects/customer/jest.config.js",
"test:common": "jest --config=./projects/common/jest.config.js",

以上。


参考URL