Angular テスト: コンポーネント テスト

Dec 06 2022
概要 前回の記事では、「単体テスト」と、これらのテストを Angular アプリケーションに適用する方法を定義しました。定義上、ビジネス ロジックはコンポーネントの外部に存在する必要があり、機能のほとんどはパイプ、ディレクティブ、およびサービスに存在することに同意します。つまり、ほとんどの単体テストはこれらの種類のクラスをテストします。

概要

前回の記事では、「単体テスト」と、これらのテストを Angular アプリケーションに適用する方法を定義しました。定義上、ビジネス ロジックはコンポーネントの外部に存在する必要があり、機能のほとんどはパイプ、ディレクティブ、およびサービスに存在することに同意します。つまり、ほとんどの単体テストはこれらの種類のクラスをテストします。その記事では、テンプレート ロジックがコンポーネントからパイプに移動された Angular コンポーネントの要点も投稿しInput()、クラス定義といくつかのテンプレートのみを残しました。いつでも、だれかが要素の要素を追加または削除する可能性があり、それらの変更をキャプチャできる単体テストが存在しないことに誰もが同意します。

したがって、単体テストを使用してコンポーネントを適切にテストできない場合は、コンポーネント、統合、またはエンドツーエンドのテストしか残されません。

統合テストは機能する可能性がありますが、定義上、統合テストは、個々のユニットをテストし、それらを組み合わせてグループとしてテストするときに発生します。したがって、たとえば、でテストできますが、場合ComponentAによってComponentBはそれで問題ないでしょう。しかし、 と統合ComponentAするとどうなるComponentCでしょうか? 最初に作成したテストは、製品を本番環境に出荷するのに十分であると自信を持って言えますか?

Angular docs によると:

Angular フレームワークの基本的な構成要素は Angular コンポーネントです…

コンポーネントは、さまざまなコンポーネントと組み合わせて使用​​し、アプリケーションを構築するように設計されています。したがって、DOM、具体的にはアクセシビリティ機能InputOutputプロパティ、および適切と思われるスタイルについて、DOM の信頼できる情報源を確保して、それが常に有効であり、テストする必要がないことを確認できるようにする必要があります。手動で。

Header コンポーネントに戻りましょう。

一見すると、テストすることはあまりありません。理想的な世界ではNameDisplayPipe、コンポーネントによって提供された値を検証し、期待どおりの値を返すテストがあることを知っているでしょう。h1しかし、誰かが誤って を に調整したらどうなるh2でしょうか? 誰かが誤ってタイトルの初期化を削除した場合はどうなりますか?

救助のためのコンポーネントテスト

コンポーネントのテストは、手動でテストすることに慣れてきた多くのことを手動でテストする必要がなくなるため、驚くべきものです。たとえば、テストを通じてコン​​ポーネントのテンプレート (最も重要な部分) の構造を定義しようと考えている開発者を、私は数人しか知りません。ただし、これらのことを手動でチェックする多くの QA や設計者を知っていますしかし、それは私たちが一般的に議論することのないものです. 機能と動作をテストすることは断言しますが、コードが本番環境に入ってからのテンプレートのテストのみに熱心です。それは単なる後付けです。

ヘッダー、ボディ、フッターを含むページのモックが与えられたとします。この記事では、body の内容は問題ではありませんが、1 つの作業項目として、1 つのスプリントで 3 つすべてを実行することにします。したがって、少なくとも 4 つのコンポーネントが存在することになります: a HeaderComponentBodyComponentFooterComponent、および他の 3 つPageComponent統合する a…

ヘッダー コンポーネントは既に作成していますが、作成していないことにしましょう。ヘッダーのモックアップがある場合、このコンポーネントで常に true にする必要があるものを定義できます。

  1. コンポーネントは、ヘッダー要素でそのコンテンツをラップする必要があります。
  2. デフォルトでは、ユーザーがログインしていない場合、ヘッダーはh1.
  3. ユーザーがログインしている場合、ヘッダーには「こんにちは、{{ ユーザー名 }}」とh1.

コンポーネントのテストには、Jasmine、Jest、または Cypress を使用できます。Jasmine と Jest では、TestBed に依存し、フィクスチャを使用して要素を取得し、それらをアサートします。Jest では、実際の DOM にテンプレートが表示されないため、実質的なメリットはほとんどありません。ジャスミンはここでうまく機能します。箱から出してすぐに、やりたいことのほとんどすべてを実行します。つまり、テストをタイムウォークして、テストのスナップショットを見ることができます。サイプレス アンバサダーとして、おそらく私がサイプレスを使用することを好むと推測したでしょう。サイプレス 10.5では、それを実現することができます!

サイプレス コンポーネント テストによる TDD

サイプレス コンポーネント テストは、サイプレス エンド ツー エンド テストと非常によく似た構文を持っています。「サイプレス テスト」の書き方がわかれば、コンポーネント テストの書き方もわかります。上記で作成した 3 つのテスト ケースを使用して、それぞれに関連するテストの仕様ファイルをすばやく構成できます。

過去に Cypress のテストを見たことがあれば、これは非常に見覚えがあるはずです。まだの場合は、各部分を見てみましょう。

ヘッダー要素内にある必要があります。

it('should contain a header', () => {    
  cy.mount(HeaderComponent);     
  cy.get('header')      
    .should('exist')      
    .should('be.visible');  
});

次のcy.get('header')コマンドはこれだけです。javascript を使用してヘッダー要素を取得し、それが存在するだけでなく可視であることをアサートします。<header></header>テンプレートに要素を追加するまでTDDを実行すると、このテストは失敗します。

デフォルトでは、ユーザーがログインしていない場合、ヘッダーは h1 で「Hello, User」と言う必要があります。

it('should have an h1 that has a greeting', () => {  
  cy.mount(HeaderComponent);     
  cy.get('h1')      
    .should('have.text', 'Hello, User');  
});

ユーザーがログインしている場合、ヘッダーには h1 で「こんにちは、{{ ユーザー名 }}」と表示されます。

it('should display a user name if name is provided', () => {    
  cy.mount(HeaderComponent, {      
    componentProperties: {        
      title: {          
        firstName: 'John',
        lastName: 'Doe'
      }      
    }    
  });       cy.get('h1')      
    .should('have.text', 'Hello, John Doe');
});

簡単ですよね?

概要

コンポーネントテストは面白い!これは新しい概念ではありませんが、Cypress が実装するまでにアクセスできたものよりも高速です。左ペインの右上にあるように、これら 3 つのテストの実行には 147 ミリ秒かかり、コンポーネントのテンプレートが既に定義されている場合、各テストの書き込みには数分もかかりません。これらのテストをこのヘッダー コンポーネントの出発点として使用すると、既に存在する 3 つの仕様に同意しない何かを誰かが変更した場合、コンポーネントが「壊れている」ことがわかり、それに対処する必要があります。これは HeaderComponent のインスタンスをテストしているだけなので、統合テストとは言えません。機能がテストされていないため、これを単体テストと呼ぶことはできません。これはコンポーネント テストです。

Angular でのコンポーネント テストについては、これで理解できましたか? Jasmine または Jest のテストはこれほどクリーンで高速ですか? あなたがこれとどのように対照的であるか教えてください!

次の章でお会いしましょう。統合テストについて説明します。