Angular テンプレートのコード カバレッジと将来性のあるテストに欠けている要素

Barbara Streisand
リリース: 2024-11-20 01:15:02
オリジナル
903 人が閲覧しました

TL;DR: Angular テストの Ahead-Of-Time (AOT) コンパイルを有効にして、正確なテンプレート コード カバレッジ、より高速なテスト実行、本番環境の対称性、将来性を確保します。テスト。

このオプションはすでに Vitest ユーザー向けに提供されており、間もなく Karma および Jest (実験的ビルダー) ユーザー向けにも提供される予定です。

? JITの何が問題なのでしょうか?

Karma、Jest、Vitest のいずれを使用している場合でも、最近まで利用可能な唯一のオプションであったため、おそらく Angular テストにジャストインタイム (JIT) コンパイルを使用していると思います。

問題は、JIT にはいくつかの重大な欠点があることです。

  • テンプレートが考慮されていないため、コード カバレッジは正確ではありません
  • テストはテンプレートをその場でコンパイルするため、速度が遅くなります
  • Angular は JIT 互換性の限界に達しているため、将来性はありません。設計上、一部の機能は JIT で実装することがまったく不可能です。
  • AOT が使用される運用環境とは対称的ではありません

⏰なぜ今?

Angular 8 と IVy の導入以来、Angular コンパイラーはテンプレートを命令に変換し始めました。これは、他の多くの利点の中でも特に、コード カバレッジ ツールがこれらの命令をテンプレートにマッピングし、それに応じてコード カバレッジを計算できることも意味します。

理論上、Angular 8 以降、AOT でテストを実行することでコード カバレッジを生成することは可能でしたが、このオプションは Karma または Jest では利用できませんでした。 Analog チームによって Vitest の Angular サポートが追加されて以来、テストで AOT を有効にすることのみが可能になりました

2024 年 11 月現在:

  • Vitest は、AOT コンパイルをサポートする唯一のオプションです。
  • AOT をサポートするための Karma と Jest Experimental Builder の公開 PR があります。

Angular Template Coverage

? AOT テストのその他の利点

⚡️ より高速なテスト実行

JIT を使用しているか AOT を使用しているかに関係なく、コンポーネントはある時点でコンパイルされることになります。主な違いは、AOT ではコンパイルが 1 回で完了し、キャッシュできるのに対し、JIT では各テスト モジュールが最終的にコンポーネントを再コンパイルする可能性があることです。

これは、AOT では変換フェーズが少し遅くても、全体のテスト実行時間は速くなるということを意味します。私が見た数字は約 20% 高速な実行を示していますが、これはテストの構造とテスト対象のシステムに大きく依存します。

?プロダクションシンメトリー

私たちは通常、信頼性を高めるために、テストを実稼働環境に対して可能な限り対称にすることを望んでいます。これは、テストの速度、テスト対象システムのサイズ、予測可能性などの他の特性とのバランスをとるため、多くの場合困難です。

AOT の興味深い点は、他の特性を損なうことなく生産の対称性を改善できることです。 AOT を使用すると、自信が高まり、より本番環境に近い動作が実現できます。

?将来性のあるテスト

さらに重要なのは、JIT が限界に達しており、Angular にとって負担になりつつあることです。たとえば、一部の Angular 機能は JIT ではサポートされていません (遅延ビューなど)。 Angular ロードマップの他の潜在的な機能 (セレクターなしのコンポーネントなど) は、おそらく、JIT では使用できません。

実際には、Angular の信号入力 (および同様の関数 API) 以来、JIT が動作するにはすでにいくつかの最小限の変換が必要です。

AOT に切り替えることで、テストを将来にわたって使用できるようになり、あらゆるイノベーションの恩恵を受けられるようになり、JIT の将来に何が起こっても備えられるようになります。

?欠点

?動的コンポーネント構成は避けるべきです

AOT をオンにすると、動的構造に依存する一部のテクニックが機能しなくなります。

たとえば、次のような使用法は機能しなくなります。

// ? This is broken with AOT.
const fixture = render(`<app-button></app-button>`, { imports: [Button] });

function render(template, { imports }) {
  @Component({
    template,
    imports,
  })
  class TestContainer {}

  return TestBed.createComponent(TestContainer);
}
ログイン後にコピー
ログイン後にコピー

ただし、AOT コンパイルをバイパスすることは依然として可能です (今のところ⚠️ ️⚠️):

function render(template, { imports }) {
  @Component({
    jit: true,
    template,
    imports,
  })
  class TestContainer {}

  return TestBed.createComponent(TestContainer);
}
ログイン後にコピー
ログイン後にコピー

私のアドバイスは、少し冗長になるかもしれませんが、そのような構造はできるだけ避け、必要に応じてテスト固有のコンポーネントを作成することを優先するです。将来的には、Angular チームは、AOT と互換性があり、定型的な要素が少ない代替案を提供する可能性があります。

?浅いテストはより困難です

浅いテストは本番環境との対称性が低いため、主要なテスト戦略にするべきではありませんが、ツールボックスに入れておくと便利な手法です。

AOT では、TestBed#overrideComponent を使用してコンポーネントのインポートをオーバーライドすることは現時点では不可能です。

回避策は、テスト フレームワークの API を使用してコンポーネントの依存関係をモジュール レベルでオーバーライドし、コンポーネントをそのテスト ダブルで置き換えることです。

たとえば、Vitest の場合:

// app.cmp.spec.ts
vi.mock('./street-map.cmp', async () => {
  return {
    StreetMap: await import('./street-map-fake.cmp').then(
      (m) => m.StreetMapFake
    ),
  };
});

// street-map-fake.cmp.ts
@Component({
  selector: 'app-street-map',
  template: 'Fake Street Map',
})
class StreetMapFake implements StreetMap {
  // ...
}
ログイン後にコピー
ログイン後にコピー

この一時的な回避策は AOT と互換性がありますが、次のようなコストがかかります。

  • 読みにくくなり、冗長になります。
  • モジュールレベルでの
  • 「モッキング」(またはテストダブルの提供)は粒度が低く、予測可能性が低い可能性があります。
  • 使用しているテスト フレームワークと高度に連携しています。

現時点では、TestBed#overrideComponent が AOT をサポートするまで、または Angular チームがより良い代替案を提供するまで、浅いテストには JIT を使用することをお勧めします。これを実現するには、*.jit.spec.ts.

のような特定のパターンに一致するテストに JIT を使用する浅いテスト用の別の設定を使用します。

??‍? Vitest を AOT でスピンしてみよう

1. Vitestをセットアップする

  • Angular CLI ユーザーの場合は、Analog の回路図を使用してください。
  • Nx ユーザーの場合、アプリケーションまたはライブラリを生成するときに vitest オプションを選択します (Nx 20.1.0 以降で利用可能)。

2.AOTを有効にする

vite.config.js ファイルを見つけて、Angular のプラグイン jit オプションを false に設定して AOT を有効にします。

// ? This is broken with AOT.
const fixture = render(`<app-button></app-button>`, { imports: [Button] });

function render(template, { imports }) {
  @Component({
    template,
    imports,
  })
  class TestContainer {}

  return TestBed.createComponent(TestContainer);
}
ログイン後にコピー
ログイン後にコピー

?コードカバレッジの構成

コード カバレッジには istanbul またはネイティブ v8 を使用するオプションがあります。何らかの理由で、まだ調査中ですが、v8 を使用すると Vitest カバレッジの再マッピングが失敗します。解決策は、代わりに istanbul を使用するように戻すことです。

1. @vitest/coverage-istanbul をインストールします

Vitest のメジャー バージョン
と一致する Vitest Istanbul バージョンをインストールしていることを確認してください。

function render(template, { imports }) {
  @Component({
    jit: true,
    template,
    imports,
  })
  class TestContainer {}

  return TestBed.createComponent(TestContainer);
}
ログイン後にコピー
ログイン後にコピー

2. 補償プロバイダーとしてイスタンブールを選択します

vite.config.mts を更新して、イスタンブールを使用したカバレッジを有効にします。

// app.cmp.spec.ts
vi.mock('./street-map.cmp', async () => {
  return {
    StreetMap: await import('./street-map-fake.cmp').then(
      (m) => m.StreetMapFake
    ),
  };
});

// street-map-fake.cmp.ts
@Component({
  selector: 'app-street-map',
  template: 'Fake Street Map',
})
class StreetMapFake implements StreetMap {
  // ...
}
ログイン後にコピー
ログイン後にコピー

?実際に見てみる

これでテストを実行できるようになります:

export default defineConfig({
  ...
  plugins: [
    angular({ jit: false }),
    ...
  ],
  ...
});
ログイン後にコピー

次に、カバレッジ アイコンをクリックして、テンプレートのコード カバレッジを確認します。 ?

Angular テンプレートのコード カバレッジと将来性のあるテストに欠けている要素

(カバレッジ フォルダーにもカバレッジ レポートがあります)

Angular Template Coverage

カバレッジはコンパイラによって生成された命令に基づいて計算されることに注意してください。つまり、次のことがわかります。

構造ディレクティブにも機能します。

Angular Structural Directive Coverage

さて、どうなるでしょうか?

このカバレッジはインライン テンプレートにも適用されます。 ?

Angular Inline Template Coverage

☢️ コードカバレッジの罠に注意してください

コード カバレッジは便利なツールですが、賢明に使用する必要があります。厳密な目標ではなく、指標として保持してください。

観察された統計的規則性は、制御目的で圧力がかかると崩れる傾向があります。

-- チャールズ・グッドハート

言い換えれば、ある対策が目標になると、それは良い対策ではなくなります。

最も単純な指標は、多くの場合、最も誤解を招きやすいことを付け加えておきます。

?次は何ですか?

Karma ユーザーは、簡単なフラグで AOT を有効にできるようになります。

Jest ユーザーには 3 つのオプションがあります:

  • 推奨: Vitest に移行します。 (? 最もスムーズな移行パスを間もなく共有するので、しばらくお待ちください)
  • AOT で実験用ビルダーを使用します。
  • jest-preset-angular AOT のサポートを待ちます。

Vitest ユーザーは今すぐ AOT のメリットを享受できます。 ?

?追加のリソース

  • ?デモリポジトリ
  • ? Angular Ahead-Of-Time (AOT) コンパイラーのドキュメント
  • ? Vitest ドキュメント
  • ? Vitest に関する Analog のドキュメント

??‍? Pragmatic Angular Testing ビデオ コースが登場しました!

Angular テンプレートのコード カバレッジと将来性のあるテストに欠けている要素

バグや、リファクタリングのたびに壊れるメンテナンスの多いテストにうんざりしている場合は、私のビデオ コース「Pragmatic Angular Testing」が役に立ちます。

Angular アプリの安定性と保守性を維持するための、実践的で信頼性の高いテスト戦略を学びましょう。 (今なら期間限定で50%オフ!)

以上がAngular テンプレートのコード カバレッジと将来性のあるテストに欠けている要素の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート