Scrivi test di accettazione e test dei componenti per il codice Ember in Discourse

I test automatizzati sono un ottimo modo per proteggere il tuo codice da regressioni future. Molti sanno come farlo nel nostro codicebase Rails con rspec, ma il lato Javascript può risultare un enigma per alcuni.

Fortunatamente, oggi è piuttosto semplice aggiungere test di base al tuo codice Ember!

Test dei Componenti

Nel precedente tutorial di questa serie abbiamo aggiunto un componente chiamato fancy-snack per visualizzare il nostro snack con uno sfondo sfumato. Scriviamo un test per esso. Crea il seguente file:

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

Per eseguire il test, apri il tuo browser sul server di sviluppo all’indirizzo /qunit?module=component%3Afancy-snack. Il tuo browser eseguirà quindi i test del componente e produrrà un output simile a “2 asserzioni su 2 superate, 0 fallite.”

Nota che, mentre sei sulla pagina /qunit, puoi eseguire anche altri test. Puoi semplicemente selezionare un nuovo test dal menu a tendina Module in alto nella schermata.

Analizziamo il test passo dopo passo per capire come funziona.

La riga template dice a Ember come vogliamo inserire il nostro componente. È esattamente lo stesso markup che useresti per posizionare il componente in un template Handlebars, quindi dovrebbe esserti familiare:

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

Nota che sta passando testSnack come parametro snack. Questo è definito nel metodo setup():

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

Ho inserito semplicemente dei dati fittizi. È tutto ciò che serve per far rendere il componente da Ember. Infine, abbiamo alcune asserzioni nel metodo 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!');
}

Se usi this.$(), hai accesso a un selettore jQuery nel tuo template. Le asserzioni qui usano quel selettore per ottenere il valore del titolo dello snack e della descrizione dello snack e confrontarli con quanto ci aspettiamo. Se i valori corrispondono, le asserzioni passeranno e il nostro test funzionerà correttamente.

Vale la pena notare che non è necessario testare ogni singola cosa in un componente come questo. Dovresti usare un po’ di buon senso e cercare di capire quali parti del tuo codice potrebbero rompersi o creare confusione per altri sviluppatori in futuro. Se testi troppe cose nel tuo template, renderà doloroso per qualcun altro in futuro modificarlo. Inizia semplicemente, testando le cose più ovvie, e col tempo imparerai.

Test di Accettazione

I test di accettazione sono spesso più facili da scrivere e possono essere più potenti dei test dei componenti, poiché testano la tua applicazione nello stesso modo in cui un utente lo farebbe nel proprio browser. Spesso inizio con i test di accettazione e, se sto creando un componente complesso, aggiungo anche dei test specifici per esso.

Ecco come possiamo scrivere un test di accettazione che visiterà la nostra rotta /admin/snack e confermerà che lo snack è stato renderizzato:

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

Il test() in questo caso è quasi leggibile come l’inglese! Il primo comando dice di visitare l’URL /admin/snack. Dopo di ciò, c’è un metodo andThen(). Questo metodo è necessario per assicurarsi che tutto il lavoro in background sia completato prima che i test continuino. Poiché Javascript e il codice Ember sono asincroni, dobbiamo assicurarci che Ember abbia finito tutto ciò che deve fare prima che le nostre asserzioni vengano eseguite. Infine, verifica se l’elemento .fancy-snack-title è presente.

Tuttavia, se esegui questo test visitando /qunit?module=Acceptance%3A%20Snack, scoprirai che il test fallirà a causa di un errore AJAX.

Se ricordi, il nostro codice include sia il lato Rails che il lato Javascript, che esegue una richiesta AJAX per ottenere i dati. Il test di accettazione ha eseguito il lato Javascript, ma non sapeva cosa fare per ottenere i dati da Rails.

Per risolvere il problema, dobbiamo aggiungere una risposta fittizia, utilizzando l’ottima libreria pretender. Apri il file test/javascripts/helpers/create-pretender.js e cerca la riga che dice:

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

Subito sotto, aggiungi una riga per restituire un oggetto snack fittizio con cui il nostro test di accettazione possa lavorare:

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

Puoi leggere il codice sopra come: “per qualsiasi richiesta a /admin/snack.json, rispondi con la seguente response.”

Se aggiorni l’URL /qunit?module=Acceptance%3A%20Snack, il tuo test di accettazione dovrebbe recuperare i dati tramite pretender e i test dovrebbero passare.

Dove andare da qui

Potresti provare a costruire una piccola funzionalità e aggiungere test per assicurarti che funzioni. Potresti anche provare a usare il TDD creando i tuoi test prima di scrivere qualsiasi codice nel front-end. A seconda di su cosa stai lavorando e delle tue preferenze personali, potresti trovare questo un modo più piacevole per procedere. Buona fortuna e buon coding :slight_smile:


Questo documento è controllato dalla versione: suggerisci modifiche su 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