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

Los tests automatizados son una excelente manera de proteger tu código contra regresiones futuras. Muchas personas están familiarizadas con cómo hacer esto en nuestra base de código de Rails con rspec, pero el lado de Javascript puede ser un tanto enigmático para algunos.

Afortunadamente, hoy en día es bastante fácil agregar pruebas básicas a tu código de Ember.

Pruebas de Componentes

En el tutorial anterior de esta serie, agregamos un componente llamado fancy-snack para mostrar nuestro snack con un fondo desvanecido. Escribamos una prueba para él. Crea 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 la prueba, abre tu navegador en tu servidor de desarrollo en /qunit?module=component%3Afancy-snack. Tu navegador ejecutará las pruebas de componentes y mostrará algo como “2 afirmaciones de 2 pasadas, 0 fallidas”.

Ten en cuenta que, en la página /qunit, puedes ejecutar otras pruebas. Simplemente selecciona una nueva prueba desde el menú desplegable Module en la parte superior de la pantalla.

Repasemos la prueba para entender cómo funciona.

La línea template le dice a Ember cómo queremos insertar nuestro componente. Es exactamente el mismo marcado que usarías para colocar el componente en una plantilla de Handlebars, por lo que debería ser familiar:

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

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

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

Simplemente he incluido algunos datos de prueba. Eso es todo lo que necesitamos hacer para que Ember renderice el componente. Finalmente, tenemos algunas afirmaciones 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 usas this.$(), obtienes acceso a un selector de jQuery en tu plantilla. Las afirmaciones aquí usan ese selector para obtener el valor del título del snack y la descripción del snack, y los comparan con lo que esperamos. Si los valores coinciden, las afirmaciones pasarán y nuestra prueba funcionará correctamente.

Vale la pena mencionar que no necesitas probar cada pequeña cosa en un componente como este. Debes usar algo de criterio e intentar identificar qué partes de tu código es probable que fallen o causen confusión a otros desarrolladores en el futuro. Si pruebas demasiadas cosas en tu plantilla, será un dolor para alguien más en el futuro modificarla. Simplemente comienza con lo básico, probando las cosas más obvias, y con el tiempo te familiarizarás con ello.

Pruebas de Aceptación

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

Así es como podemos escribir una prueba de aceptación que visite nuestra ruta /admin/snack y confirme 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");
  });
});

¡La 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 asegurarse de que todo el trabajo en segundo plano haya terminado antes de que continúen las pruebas. Dado que Javascript y el código de Ember son asíncronos, necesitamos asegurarnos de que Ember haya terminado todo lo que necesita hacer antes de que se ejecuten nuestras afirmaciones. Finalmente, verifica si el elemento .fancy-snack-title está presente.

Sin embargo, si ejecutas esta prueba visitando /qunit?module=Acceptance%3A%20Snack, encontrarás que la prueba fallará debido a un error de AJAX.

Si lo recuerdas, nuestro código incluye tanto un lado de Rails como un lado de Javascript que realiza una solicitud AJAX para obtener sus datos. La prueba de aceptación ejecutó el lado de Javascript, pero no sabía qué hacer para obtener sus datos de Rails.

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

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

Justo debajo de ella, agrega una línea para devolver un objeto de snack falso con el que pueda trabajar nuestra prueba de aceptación:

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

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

Si actualizas la URL /qunit?module=Acceptance%3A%20Snack, tu prueba de aceptación debería recuperar sus datos mediante pretender y las pruebas deberían pasar.

A dónde ir a partir de aquí

Podrías intentar construir una pequeña característica y agregar pruebas para asegurarte de que funcione. Incluso podrías intentar usar TDD creando tus pruebas antes de escribir cualquier código en el frontend. Dependiendo de en qué estés trabajando y de tus preferencias personales, podrías encontrar que esta es una forma más agradable de hacerlo. ¡Buena suerte y feliz codificación :slight_smile:


Este documento está controlado por versiones: sugiere 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