Akzeptanztests und Komponententests für Ember-Code in Discourse schreiben

Automatisierte Tests sind eine großartige Möglichkeit, Ihren Code vor zukünftigen Regressionen zu schützen. Viele Leute wissen, wie das in unserer Rails-Codebasis mit rspec funktioniert, aber die Javascript-Seite kann für manche ein ziemliches Rätsel sein.

Glücklicherweise ist es heutzutage ziemlich einfach, grundlegende Tests zu Ihrem Ember-Code hinzuzufügen!

Komponententests

Im vorherigen Tutorial dieser Serie haben wir eine Komponente namens fancy-snack hinzugefügt, um unseren Snack mit einem verblassenden Hintergrund anzuzeigen. Schreiben wir einen Test dafür. Erstellen Sie die folgende Datei:

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!"
    );
  },
});

Um den Test auszuführen, öffnen Sie Ihren Browser auf Ihrem Entwicklungsserver unter /qunit?module=component%3Afancy-snack. Ihr Browser führt dann die Komponententests durch und gibt etwas wie „2 assertions of 2 passed, 0 failed“ aus.

Beachten Sie, dass Sie, während Sie sich auf der /qunit-Seite befinden, andere Tests ausführen können. Sie können einfach einen neuen Test aus dem Dropdown-Menü „Module“ oben auf dem Bildschirm auswählen.

Gehen wir den Test Schritt für Schritt durch, um zu verstehen, wie er funktioniert.

Die Zeile template teilt Ember mit, wie wir unsere Komponente einfügen möchten. Es ist exakt die gleiche Markierung, die Sie verwenden würden, um die Komponente in einer Handlebars-Vorlage zu platzieren, daher sollte sie vertraut sein:

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

Beachten Sie, dass testSnack als Parameter snack übergeben wird. Dieser wird in der setup()-Methode definiert:

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

Ich habe einfach einige Dummy-Daten eingefügt. Das ist alles, was wir tun müssen, damit Ember die Komponente rendert. Schließlich haben wir ein paar Behauptungen in der test()-Methode:

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!');
}

Wenn Sie this.$() verwenden, erhalten Sie Zugriff auf einen jQuery-Selektor in Ihrer Vorlage. Die Behauptungen hier verwenden diesen Selektor, um den Wert des Snack-Titels und der Snack-Beschreibung abzurufen und sie mit dem zu vergleichen, was wir erwarten. Wenn die Werte übereinstimmen, werden die Behauptungen bestanden und unser Test funktioniert.

Es ist erwähnenswert, dass Sie nicht jedes kleine Detail in einer Komponente wie dieser testen müssen. Sie sollten etwas Ermessen walten lassen und versuchen herauszufinden, welche Dinge in Ihrem Code wahrscheinlich kaputt gehen oder bei anderen Entwicklern in Zukunft für Verwirrung sorgen könnten. Wenn Sie zu viele Dinge in Ihrer Vorlage testen, wird es für jemand anderen in der Zukunft mühsam, sie zu ändern. Fangen Sie einfach klein an, testen Sie die offensichtlichsten Dinge, und mit der Zeit bekommen Sie den Dreh raus.

Akzeptanztests

Akzeptanztests sind oft einfacher zu schreiben und können leistungsfähiger sein als Komponententests, da sie Ihre Anwendung genauso testen, wie es ein Benutzer in seinem Browser tun würde. Ich beginne oft mit Akzeptanztests und füge dann Tests für komplizierte Komponenten hinzu.

Hier ist, wie wir einen Akzeptanztest schreiben können, der unsere Route /admin/snack besucht und bestätigt, dass der Snack gerendert wurde:

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");
  });
});

Das test() liest sich in diesem Fall fast wie Englisch! Der erste Befehl besagt, dass die URL /admin/snack besucht werden soll. Danach gibt es eine andThen()-Methode. Diese Methode ist notwendig, um sicherzustellen, dass alle Hintergrundarbeiten abgeschlossen sind, bevor die Tests fortgesetzt werden. Da Javascript- und Ember-Code asynchron ist, müssen wir sicherstellen, dass Ember alles erledigt hat, was es tun muss, bevor unsere Behauptungen ausgeführt werden. Schließlich wird getestet, ob das Element .fancy-snack-title vorhanden ist.

Wenn Sie diesen Test jedoch ausführen, indem Sie /qunit?module=Acceptance%3A%20Snack besuchen, werden Sie feststellen, dass der Test aufgrund eines AJAX-Fehlers fehlschlägt.

Wenn Sie sich erinnern, enthielt unser Code sowohl eine Rails-Seite als auch eine Javascript-Seite, die eine AJAX-Anfrage stellten, um ihre Daten abzurufen. Der Akzeptanztest führte die Javascript-Seite aus, wusste aber nicht, was zu tun war, um seine Daten von Rails zu erhalten.

Um dies zu beheben, müssen wir eine gefälschte Antwort mithilfe der ausgezeichneten pretender-Bibliothek hinzufügen. Öffnen Sie die Datei test/javascripts/helpers/create-pretender.js und suchen Sie nach der Zeile, die besagt:

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

Fügen Sie direkt darunter eine Zeile hinzu, um ein gefälschtes Snack-Objekt für unseren Akzeptanztest zurückzugeben:

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

Sie können den obigen Code als „für jede Anfrage an /admin/snack.json mit der folgenden response antworten“ lesen.

Wenn Sie die URL /qunit?module=Acceptance%3A%20Snack aktualisieren, sollte Ihr Akzeptanztest seine Daten über Pretender abrufen und die Tests sollten bestanden werden.

Wie geht es weiter

Sie könnten versuchen, eine kleine Funktion zu erstellen und Tests hinzuzufügen, um sicherzustellen, dass sie funktioniert. Sie könnten sogar versuchen, TDD zu verwenden, indem Sie Ihre Tests erstellen, bevor Sie Code auf der Frontend-Seite schreiben. Abhängig davon, woran Sie arbeiten und Ihren persönlichen Vorlieben, finden Sie dies möglicherweise eine angenehmere Vorgehensweise. Viel Glück und viel Spaß beim Coden :slight_smile:


Dieses Dokument wird versioniert – schlagen Sie Änderungen auf github vor.

15 „Gefällt mir“

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 „Gefällt mir“

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 „Gefällt mir“

Nur zur Information: Der Pfad /qunit ist veraltet. Es ist jetzt /tests. Ich habe eine Weile gebraucht, um das herauszufinden :slight_smile:

1 „Gefällt mir“