Scrivi test di accettazione e test di componente per il codice Ember in Discourse

Automated test(自動テスト)は、将来的なリグレッションからコードを保護するための優れた方法です。多くの人は、Railsのコードベースでrspecを使ってこれを行う方法に精通していますが、JavaScript側は一部の人にとっては謎めいたものであることがあります。

幸いなことに、今日ではEmberコードに基本的なテストを追加するのはかなり簡単です!

コンポーネントテスト

このシリーズの前のチュートリアルでは、スナックをフェードする背景で表示するためのfancy-snackというコンポーネントを追加しました。それに対してテストを書いてみましょう。以下のファイルを作成してください。

test/javascripts/components/snack-test.js

import componentTest from "helpers/component-test";

moduleForComponent("fancy-snack", { integration: true });

componentTest("test the rendering", {
  template: "{{fancy-snack snack=testSnack}}",

  setup() {
    this.set("testSnack", {
      name: "Potato Chips",
      description: "Now with extra trans fat!",
    });
  },

  test(assert) {
    assert.equal(this.$(".fancy-snack-title h1").text(), "Potato Chips");
    assert.equal(
      this.$(".fancy-snack-description p").text(),
      "Now with extra trans fat!"
    );
  },
});

テストを実行するには、開発サーバーで/qunit?module=component%3Afancy-snackにブラウザを開きます。その後、ブラウザがコンポーネントテストを実行し、「2 assertions of 2 passed, 0 failed.」のような結果が出力されます。

/qunitページにいる間は、他のテストを実行できることに注意してください。画面上部のModuleドロップダウンボックスから新しいテストを簡単に選択できます。

テストがどのように機能するかを理解するために、ステップバイステップで見ていきましょう。

template行は、コンポーネントをどのように挿入したいかをEmberに伝えます。これは、handlebarsテンプレートでコンポーネントを配置するときに使用するのと同じマークアップなので、馴染みがあるはずです。

template: '{{fancy-snack snack=testSnack}}',

これは、testSnacksnackパラメーターとして渡していることに注意してください。これはsetup()メソッドで定義されています。

setup() {
  this.set('testSnack', {
    name: 'Potato Chips',
    description: 'Now with extra trans fat!'
  });
},

ここにいくつかのダミーデータを入れました。Emberにコンポーネントを描画させるために必要なのはこれだけです。最後に、test()メソッドにいくつかのアサーションがあります。

test(assert) {
  assert.equal(this.$('.fancy-snack-title h1').text(), 'Potato Chips');
  assert.equal(this.$('.fancy-snack-description p').text(), 'Now with extra trans fat!');
}

this.$()を使用すると、テンプレート内でjQueryセレクターにアクセスできます。ここでのアサーションは、そのセレクターを使用してスナックのタイトルとスナックの説明の値を取得し、期待される値と比較します。値が一致すれば、アサーションはパスし、テストはすべて機能します。

このようなコンポーネントのすべてをテストする必要はないことに注意する価値があります。裁量を使用し、コード内の何が将来的に壊れたり、他の開発者に混乱を招いたりする可能性があるかを把握するように努めるべきです。テンプレートでテストが多すぎると、将来誰かがそれを変更するのが面倒になります。まずは小さく、最も明白なことからテストを始め、そのうちにコツを掴むでしょう。

受け入れテスト

受け入れテストは、記述が容易で、ユーザーがブラウザで行うのと同じようにアプリケーションをテストするため、コンポーネントテストよりも強力な場合があります。私は受け入れテストから始めることが多く、複雑なコンポーネントを作成している場合は、それらのテストも追加します。

/admin/snackルートにアクセスし、スナックがレンダリングされたことを確認する受け入れテストを次に示します。

test/javascripts/acceptance/snack-test.js

import { acceptance } from "helpers/qunit-helpers";
acceptance("Snack");

test("Visit Page", function (assert) {
  visit("/admin/snack");
  andThen(() => {
    assert.ok(exists(".fancy-snack-title"), "the snack title is present");
  });
});

この場合のtest()は、ほとんど英語のように読めます!最初のコマンドは、/admin/snackのURLにアクセスするように指示します。その後にはandThen()メソッドがあります。このメソッドは、テストが続行する前にすべてのバックグラウンド処理が完了していることを保証するために必要です。JavaScriptとEmberのコードは非同期であるため、アサーションが実行される前にEmberが必要なすべての処理を完了していることを確認する必要があります。最後に、.fancy-snack-title要素が存在するかどうかをテストします。

しかし、/qunit?module=Acceptance%3A%20Snackにアクセスしてこのテストを実行すると、AJAXエラーのためテストが失敗することに気づくでしょう。

思い出していただければ、私たちのコードにはRails側と、データを取得するためにAJAXリクエストを実行したJavaScript側の両方が含まれています。受け入れテストはJavaScript側を実行しましたが、Railsからデータを取得するために何をすべきかを知りませんでした。

これを修正するには、優れたpretenderライブラリを使用して、偽の応答を追加する必要があります。test/javascripts/helpers/create-pretender.jsファイルを開き、次の行を探します。

this.get("/admin/plugins", () => response({ plugins: [] }));

そのすぐ下に、受け入れテストが使用できるように偽のスナックオブジェクトを返す行を追加します。

this.get("/admin/snack.json", () => {
  return response({ name: "snack name", description: "snack description" });
});

上記のコードは、「/admin/snack.jsonへのすべてのリクエストに対して、次のresponseで応答する」と読むことができます。

/qunit?module=Acceptance%3A%20SnackのURLを更新すると、受け入れテストはpretender経由でデータを取得し、テストはパスするはずです。

次のステップ

小さな機能を作成し、それが機能することを確認するためのテストを追加してみてください。フロントエンドでコードを書く前にテストを作成することで、TDDを試すこともできます。取り組んでいる内容や個人の好みに応じて、こちらの方が楽しい方法だと感じるかもしれません。頑張ってください、そしてハッピーコーディングを: )


このドキュメントはバージョン管理されています - 変更の提案はgithubで行ってください。

15 Mi Piace

My prior experience in writing qunit tests was based on the other howto

i.e. “acceptance” was simply

acceptance("Purple Tentacle", { loggedIn: true });

I have seen in other plugins where the test code contained “fake” JSON to test against. I wasn’t sure if that would be as good as testing against “real” data, so I wanted to avoid doing it that way.

The six tests passed, but I got a couple of rather angry looking “unhandled request” errors.

After finding an example of some “setup” code, I tried it and it solved the errors.

It works, but I’m not really sure why, nor why it’s needed for some but not for the majority of plugins I’ve seen that have qunit tests.

3 Mi Piace

For a long time we weren’t great with testing plugins, so not many people followed our example and added tests.

You are right to add a response using pretender to handle AJAX calls.

4 Mi Piace

Solo una nota: il percorso /qunit è obsoleto. Ora è /tests. Mi ci è voluto un po’ per capirlo :slight_smile:

1 Mi Piace