Screenshot testing con Cypress
Tags: angular, testing, cypress, e2e
Published: 2020-10-28 04:18:49

Déjenme inciar con estas 2 preguntas:

1.  Hicieron modificaciones al CSS global y ¿no saben si algún componente se afecto?
2. ¿Les ha pasado que han realizado una migración de librerías a versiones más nuevas y no saben si los componentes se afectaron visualmente?

¿Cómo lo verifican? o nada más se persignan 🙏y le dan commit 😂.

El screenshot testing nos viene a en robustecer nuestras suite de pruebas, al tomar literalmente un screenshot (captura de pantalla) al componente, elemento o pagina que definamos.

### 🤔 ¿Cómo funciona?

Una vez la sección este lista, verificada y se encuentre en el estado visual que deseamos, se le tomará una captura de pantalla, el cual llamaremos "golden screenshot" 🌟y esta será utilizada para como comparativo cada vez que se corra la prueba. 

### ❓¿Quién utiliza screenshots testing como pruebas?

Es un practica común, pero para poner un ejemplo de un grande la industria, Google en sus productos lo utiliza. Cuando el equipo de Angular anunció Ivy (su nuevo motor de renderización), migraron sus proyecto a la ultima versión con el objetivo de saber si habían diferencias entre una versión y otra, corrieron miles de pruebas (literalmente, puede ver más [acá](https://youtu.be/O0xx5SvjmnU?list=PLOETEcp3DkCpimylVKTDe968yNmNIajlR&t=1298)) entre ellas screenshot testing de los cuales el 97% pasaron, esto sirvió como prueba de regresión y  les permitió poder analizar las diferencias.

### 🤓¿Qué debo de considerar?

- Estas pruebas lo que hacen es comparar imágenes así que toman más tiempo que un unit test generalmente.
- Cada vez que actualices un componente/sección/pagina y sabes que lo estás haciendo correctamente vas a tener que actualizar el golden screenshot.

### ⏰ ¿Cuándo debo utilizarlas?

- Cuando estas creando muchas pruebas para asegurarte que propiedades de CSS se están aplicando.
- Cuando vas a realizar una migración de una librería que puede afectar las renderización (por actualizar boostrap o material)
- Cuando quieres implementar y automatizar algún otro mecanismo como prueba de regresión.

### ⚡️¿Son parecidas a los snapshots en Jest?

Aunque el principio de captura es el mismo, la diferencia esta en que los snapshots de Jest toman una copia del código de un elemento y lo usara para comparar cada vez que se corran las pruebas pero esto no nos puede asegurar que elemento siempre se renderice de la misma manera. 

### 🔨 ¿Cómo creo este tipo de pruebas?

Vamos a utilizar Cypress, el cual es una herramienta moderna que nos permite correr pruebas E2E al front-end. 

Nota: Esta no es la única manera de hacer este tipo de pruebas existen servicios (como [Applitools](https://applitools.com/)), plugins y otros frameworks para hacer lo mismo

### 💡 Ejemplo

1. Primero, necesitamos instalar Cypress junto con `cypress-image-snapshot`:

    `npm i -D cypress cypress-image-snapshot`

2. Definimos 2 nuevos NPM scripts:

`"cypress": "cypress"` y `"cypress:open": "npm run cypress -- open"`

Note: el primer comando nos da libertad de usar cypress con otras opciones no solo open.

3.Corremos `npm run cypress:open`. La primera vez que se corra Cypress, por defector, creará una estructura para los E2E tests.

4.Actualizar los siguientes archivos

`plugins/index.js`

```jsx
const {
  addMatchImageSnapshotPlugin,
} = require('cypress-image-snapshot/plugin');

module.exports = (on, config) => {
  addMatchImageSnapshotPlugin(on, config);
}
```

`support/commands.js`

```jsx
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';

if (Cypress.config('isInteractive')) {
  Cypress.Commands.add('matchImageSnapshot', () => {
    cy.log('Skipping snapshot 👀')
  })
} else {
  addMatchImageSnapshotCommand()
}
```

5.Generé una aplicación en Angular, que muestra un un Charmander "fake" en la ruta principal.

![st-1](https://dev-to-uploads.s3.amazonaws.com/i/7rkdhixnl77z00675ld3.png)
  
Así que vamos a crear un escenario en el que se tome una captura y la utilice como comparativo cada vez que se corra la prueba

```jsx
describe('Home screenshot', () => {
  it('debe tomar screenshot de toda la pagina', () => {
    cy.visit('/');
    cy.matchImageSnapshot('home');
  });
});

```

Con este comando vas a poder correr las pruebas y generar las imagenes:

`npm run cypress run`

![st-2](https://dev-to-uploads.s3.amazonaws.com/i/2a1ox2sy9c1be6n00w9x.png)
 

6.Para probar que la prueba este funcionando, cambie la imagen por un Charmander real. Corremos de nuevo los tests.

![Screenshot 2020-10-27 at 10.13.09 PM](https://dev-to-uploads.s3.amazonaws.com/i/6dxw24ndi0ghtg35skf2.png)
 

7.¡BOOM! Falló. 
![death star](https://i.imgur.com/pTwdOOR.jpg)

Si estas seguro del cambio nada mas debes de agregar este flag `-env updateSnapshots=true` al comando anterior  para actualizar la captura. Ahora las prueba pasa de nuevo.
![Screenshot 2020-10-27 at 10.15.33 PM](https://dev-to-uploads.s3.amazonaws.com/i/1s0ihq7qu8d0w2kyu3dt.png)
 
### 👀 Conclusión

El screenshot testing es un escudo más que nos ayuda a automatizar y evitar las regresiones visuales. En proyecto grandes hacer QA manual se empieza a volver lento, costoso y se aumenta el riesgo de un error humano.

Puedes encontrar el ejemplo completo acá
https://github.com/mahcr/angular-screenshot-testing

—

¿Quieres invitarme a un cafecito?

[![0_qyvuaXnWMWm33Ea8](https://dev-to-uploads.s3.amazonaws.com/i/5t90yzlkmfy7vnth7u58.png)](https://www.buymeacoffee.com/marianocodes)