Escribe pruebas de aceptación y pruebas de componentes para código Ember en Discourse

Los tests automatizados son una excelente manera de proteger su código contra regresiones futuras. Mucha gente está familiarizada con cómo hacer esto en nuestra base de código Rails con rspec, pero el lado de Javascript puede ser algo enigmático para algunos.

¡Afortunadamente, hoy en día es bastante fácil agregar tests básicos a su código Ember!

Tests de Componentes

En el tutorial anterior de esta serie, agregamos un componente llamado fancy-snack para mostrar nuestro snack con un fondo que se desvanece. Escribamos un test para él. Cree el siguiente archivo:

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

Para ejecutar el test, abra su navegador en su servidor de desarrollo en /qunit?module=component%3Afancy-snack. Su navegador realizará entonces las pruebas de componentes y mostrará algo como “2 assertions of 2 passed, 0 failed.”

Tenga en cuenta que mientras esté en la página /qunit puede ejecutar otros tests. Simplemente puede seleccionar un nuevo test del menú desplegable Module en la parte superior de la pantalla.

Analicemos el test para entender cómo funciona.

La línea template le dice a Ember cómo nos gustaría insertar nuestro componente. Es exactamente el mismo marcado que usaría para colocar el componente en una plantilla handlebars, por lo que debería resultarle familiar:

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

Tenga en cuenta que está pasando testSnack como parámetro snack. Eso se define en el método setup():

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

Acabo de poner algunos datos ficticios. Eso es todo lo que necesitamos hacer para que Ember renderice el componente. Finalmente, tenemos un par de aserciones en el método 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!');
}

Si usa this.$() obtiene acceso a un selector jQuery en su plantilla. Las aserciones aquí usan ese selector para obtener el valor del título del snack y la descripción del snack y compararlos con lo que esperamos. Si los valores coinciden, las aserciones pasarán y nuestro test funcionará.

Vale la pena señalar que no necesita probar cada pequeña cosa en un componente como este. Debe usar algo de discreción e intentar descubrir qué cosas en su código es probable que fallen o causen confusión a otros desarrolladores en el futuro. Si prueba demasiadas cosas en su plantilla, significará que será una molestia para otra persona en el futuro cambiarla. Simplemente comience poco a poco, probando las cosas más obvias, y con el tiempo lo dominará.

Tests de Aceptación

Los tests de aceptación a menudo son más fáciles de escribir y pueden ser más potentes que los tests de componentes, ya que prueban su aplicación de la misma manera que lo haría un usuario en su navegador. A menudo empiezo con tests de aceptación y luego, si estoy creando un componente complicado, también agrego tests para él.

Así es como podemos escribir un test de aceptación que visitará nuestra ruta /admin/snack y confirmará que el snack se renderizó:

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

El test() en este caso ¡casi se lee como inglés! El primer comando dice visitar la URL de /admin/snack. Después de eso, hay un método andThen(). Este método es necesario para asegurar que todo el trabajo de fondo haya finalizado antes de que los tests continúen. Dado que el código Javascript y Ember es asíncrono, debemos asegurarnos de que Ember haya terminado todo lo que necesita hacer antes de que se ejecuten nuestras aserciones. Finalmente, comprueba si el elemento .fancy-snack-title está presente.

Sin embargo, si ejecuta este test visitando /qunit?module=Acceptance%3A%20Snack, encontrará que el test fallará, debido a un error AJAX.

Si lo recuerda, nuestro código incluye tanto un lado Rails como un lado Javascript que realizó una solicitud AJAX para obtener sus datos. El test de aceptación ejecutó el lado Javascript, pero no supo qué hacer para obtener sus datos de Rails.

Para solucionar esto, necesitamos agregar una respuesta falsa, utilizando la excelente biblioteca pretender. Abra el archivo test/javascripts/helpers/create-pretender.js y busque la línea que dice:

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

Justo debajo, agregue una línea para devolver un objeto snack falso para que nuestro test de aceptación funcione:

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

Puede leer el código anterior como “para cualquier solicitud a /admin/snack.json, responda con la siguiente response.”

Si actualiza la URL /qunit?module=Acceptance%3A%20Snack, su test de aceptación debería recuperar sus datos a través de pretender y los tests deberían pasar.

¿A dónde ir desde aquí?

Podría intentar desarrollar una pequeña funcionalidad y agregar tests para asegurarse de que funciona. Incluso podría intentar usar TDD creando sus tests antes de escribir cualquier código en el front end. Dependiendo de lo que esté haciendo y de sus preferencias personales, podría encontrar que esta es una forma más agradable de proceder. ¡Buena suerte y feliz codificación! :slight_smile:


Este documento está controlado por versiones: sugiera cambios en github.

15 Me gusta

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 Me gusta

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 Me gusta

Solo una nota de que la ruta /qunit está obsoleta. Ahora es /tests. Me tomó un tiempo darme cuenta :slight_smile:

1 me gusta