Realizar tests E2E forma parte de lo que se considera “buenas prácticas” a la hora de desarrollar una aplicación.

Tras haber estado trabajando con TestCafé y comprobar que es una herramienta útil, confiable y fácil de usar, comparto en este post mis impresiones y una primera toma de contacto con esta plataforma. ¡Arrancamos!

¿Qué son los tests “End to End”?

Los tests E2E completan a los tests unitarios y de integración. Concretamente validan el flujo de una aplicación de inicio a final, se comprueba que el comportamiento es el esperado, que los componentes de la aplicación trabajan de forma conjunta, que existe integración de los datos de principio a final...

También nos ayuda a averiguar si se requieren elementos externos: API, DB…, que a su vez serán también testeados y validados.

TestCafé

Si estamos desarrollando en un framework o librería de Javascript (como React, Vue o Angular), es una de las herramientas más recomendadas para nuestros Tests E2E automáticos.

Además se puede integrar en los ciclos de integración continua y es fácil de usar. Es una herramienta para Node desarrollada por Developer Express Inc (DevExpress).

Instalación

Se instalará globalmente vía npm o yarn.


yarn global add testcafe
npm -g install testcafe

¡Hagamos un Test!

Para el caso de ejemplo he subido a bitbucket un simple formulario adaptado del ejemplo de Testcafe con su test correspondiente, os lo podéis consultar aquí.

Los tests son escritos en Javascript, también soporta TypeScript, así que los archivos serán de extensión .js o .ts.

Emplearemos la funcionalidad asíncrona async/await, si no estás familiarizado puedes echarle aquí un ojo.

Con el objetivo de tener unos test estructurados y de fácil mantenimiento, utilizaremos el patrón Page Object Model (POM), esto consiste en tener los selectores, URLs y constantes que vayamos a emplear separados en un fichero “page”, que después importaremos en nuestro test y asignaremos posteriormente la acción a realizar de cada elemento.

Imagina que posteriormente se modifican componentes, URLs… solo tendrás que acceder a la página para alterar los elementos, el test se mantiene intacto.

Lo primero que haremos es crear nuestros archivos de página y de test: test.js y page-model.js. Dentro de page-model.js lo primero a importar es el selector de Testcafé:


import { Selector } from 'testcafe';

Mediante el “Selector” de Testcafé podemos seleccionar como haríamos en JQuery por clases, ID’s y/o elementos html que definiremos en el constructor de nuestra clase JS.


export default class Page {
    constructor () {
        this.nameInput             = Selector('#developer-name');
        this.triedTestCafeCheckbox = Selector('#tried-test-cafe');
        this.populateButton        = Selector('#populate');
…

Por ejemplo, tenemos un input en nuestro html con la ID=”developer-name”, lo declaramos mediante el Selector y asignándole un nombre:


this.nameInput             = Selector('#developer-name');

Podemos crear una clase para un elemento y definir sus propiedades, luego se puede instanciar seteando éstas. En el ejemplo es el caso de Feature”, declaramos que tiene un texto como label y que es un checkbox, debe buscar ‘input[type=checkbox]’.

En la clase Page observamos que se instancia Feature dentro de un array [...], mediante new Feature(‘...’) al pasarle el string si observamos la clase, veremos que buscará que sea un checkbox, y que el label coincida con el texto enviado.

Y declarando elementos, o clases adicionales creamos nuestra Página de Modelo de Objetos. Aquí la podéis encontrar.

¡Vamos con la página de test!

Lo primero que haremos es importar la Página que hemos creado anteriormente:


import Page from './page-model';

Después emplearemos el “fixture”, que no es más que el nombre de nuestro test. Si tuviéramos varios y quisiéramos ejecutar uno en concreto, nos referiríamos a él por este nombre.

El siguiente paso es crear la página ya importada: const page = new Page(); e iremos llamando a los elementos declarados en la página. page.nameInput, por ejemplo.

Vamos a comenzar a construir nuestros tests, ¿qué podemos hacer con Testcafé? ¡Muchísimas cosas! Por ejemplo:

Podéis consultar aquí la API de la documentación de Testcafé para ver la lista completa.

En la función test escribiremos una descripción de lo que se testea en ese momento, así después verás si el test pasa o falla y dónde lo ha hecho, y se creará la función asíncrona (async, await) “t”.

Se observa la función asíncrona y las instrucciones que debe completar, escribir texto (typeText), reemplazarlo (replace:true), etc... y comprobar el resultado. Veamos un ejemplo:


test('Escribir algo', async t => {
   await t
       .typeText(page.nameInput, 'Peter') // Escribir un nombre
       .typeText(page.nameInput, 'Paker', { replace: true }) // Cambiar por apellido
       .typeText(page.nameInput, 'r', { caretPos: 2 }) // Corregir apellido
       .expect(page.nameInput.value).eql('Parker'); // Comprobar resultado
});

Si todo se cumple satisfactoriamente, en consola aparecerá el check de satisfactorio al test “Escribir algo”. Puedes ver aquí el test completo.

Una vez que tenemos completo nuestro test, la Página POM y el test en sí, podemos lanzarlo. Como cualquier otro script, podemos introducirlo en el package.json bajo la orden de “yarn test” o podemos ejecutarlo manualmente.


"scripts": {
   "test": "testcafe all test.js"
 }
“all” -> todos los browsers que tengamos

Como ves, soporta la mayoría de browsers actuales, de escritorio y móvil. Para lanzarlo en líneas generales emplearemos testcafe browser test/fixture. Si es un test, el archivo directamente; si es una fixture añadiremos -f “nombre de la fixture”.

También podemos incluir debugger en nuestro test y lanzarlo para que podamos hacer paradas en este caso la instrucción es --inspect --debug-brk + browser.

Al ejecutarlo nos abrirá el browser seleccionado o browsers seleccionados abriendo nuestra aplicación y pasando los tests.

En consola, si todo va bien, deberemos el resultado correspondiente:

Así muestra los fallos, nos indica dónde ha fallado y por qué, en este caso se cambió el nombre de un selector, por lo tanto, no podía encontrarlo:

Más cosas que podemos hacer con TestCafé es mock de respuestas a llamadas HTTP, de dos formas diferentes:


let mock = RequestMock()
    .onRequestTo('http://nuestra_url/recurso')
    .respond({data: ‘respuesta’});

Y como está basado en Node, también podemos especificar aún más la respuesta con res/send:


let mock = RequestMock()
    .onRequestTo('http://nuestra_url/recurso')
    .respond((req, res) => {
        res.headers['x-nuestro-header'] = 'nuestro-value';
        res.statusCode = '200';
        const parsedUrl = url.parse(req.path, true);
          });

Para incluirlo en nuestros test, deberemos importar:


import { RequestMock } from 'testcafe';

Y añadir a nuestro test el mock:


test
.requestHooks(mock)
('Escribir algo', async t => {...

Conviene repasar los comandos y funcionalidades a la hora de lanzar nuestros tests, por ejemplo, para incluirlo en nuestro ciclo de vida continuo es interesante la opción de header-less, o lo que es lo mismo, sin lanzar el navegador. En el ejemplo anterior habría que añadir :headless y quedaría tal que así:


testcafe "chrome:headless" test.js

Después de esta breve introducción a Testcafé, os invito a trastear con él para aprender nuevas funcionalidades. ¿Te animas?

Enlaces de interés

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.