"La calidad requiere hacerlo bien incluso cuando nadie te est谩 mirando"

-- 鉁嶏笍 Henry Ford

Para continuar aprendiendo cypress y adem谩s enfrentarnos a situaciones cotidianas voy a cambiar de ejemplo. Ahora ser谩 una aplicaci贸n desarrollada en Angular (podr铆a ser React o Vue, es lo mismo) y que consume un API rest.

El problema de las SPA

Estas aplicaciones on conocidas porque generan el html din谩micamente ejecutando JavaScript. Aunque responden a muchas rutas, t茅cnicamente son una 煤nica p谩gina con todo el c贸digo necesario para mostrar vistas seg煤n se requiera, es decir una Single Page Application

El problema es que al solicitar una ruta al servidor, este realmente no la conoce. De hecho devuelve siempre la misma p谩gina vac铆a para que sea el navegador el que agregue contenido. Una soluci贸n sencilla es no solicitar la p谩gina destino directamente, si no suponer que nos llegar谩 la ra铆z y proceder a la navegaci贸n manual simulando un click por parte del usuario.

El problema de las API

Con las llamadas a API remota nos enfrentamos a un problema distinto: la integraci贸n de distintos sistemas. Porque eso es lo que ocurre, en realidad tenemos dos aplicaciones ejecut谩ndose en dos entornos. Por un lado la web en el navegador y por otro el API en un servidor m谩s o menos lejano.

A pesar de que estas pruebas son de integraci贸n de alto nivel, es muy recomendable desacoplar estos dos 谩mbitos. Al menos si lo que queremos es comprobar la funcionalidad web, porque un fallo en el back invalidar铆a nuestras pruebas front.

Fixtures

La soluci贸n de Cypress es sencillamente elegante. Se trata de usar un doble de pruebas, concretamente un stub, que responde con datos fijos las llamadas esperadas.

Ejemplo completo

Te copio aqu铆 el c贸digo m谩s significativo que aparece en el proyecto laboratorio.

Primero, como siempre, definimos la funcionalidad que vamos a probar. Recuerda que las pruebas ayuda a documentar funcionalmente la aplicaci贸n.

FEATURE:     list my current projects
As a:        user with involved in projects
I want to:   get a list of them
In order to: follow up my work

En este caso el SUT es otra to do list esta vez desarrollada en Angular https://angularbuilders.github.io/angular-budget

El escenario que quiero probar es otro sencillo happy path

Scenario: complete a task
  GIVEN: An API with 2 projects
  WHEN: I visit the projects page
  THEN: should show 2 items on the projects list

Que se traduce en c贸digo cypress de manera casi literal

describe('GIVEN: An API with 2 projects', () => {
  before(() => {
    const stubbedApiUrl = 'https://api-base.herokuapp.com/api/pub/projects';
    const fixtureData = 'fx:projects';
    cy.server();
    cy.route(stubbedApiUrl, fixtureData);
  });
  context('WHEN: I visit the projects page', () => {
    before(() => {
      const homeSpaUrl = 'https://angularbuilders.github.io/angular-budget';
      cy.visit(homeSpaUrl);
      cy.get('a').contains('Projects').click();
    });
    it('THEN: should show 2 items on the projects list', () => {
      const expectedListItemsLength = 2;
      const selectorListItems = 'section > ul > li';
      cy.get(selectorListItems).should('have.length', expectedListItemsLength);
    });
  });
});

Simplemente llamar la atenci贸n sobre la navegaci贸n forzada por ser una SPA y el uso de la fixture para interceptar las llamadas al API devolviendo datos fake

[
  {
    "name": "dummy one",
    "projectId": 1,
    "_id": "1",
    "owner": "tester"
  },
  {
    "name": "two dummies",
    "projectId": 2,
    "_id": "2",
    "owner": "tester"
  }
]

Con esto te puedes hacer una idea clara de las capacidades de Cypress y de la importancia y retorno de inversi贸n de las pruebas funcionales e2e.