Tests E2E en el flujo de trabajo de Integración Continua
La Integración Continua es la práctica de fusionar todas las copias de trabajo del desarrollador en una línea principal compartida. End to End Testing es la metodología para garantizar que las aplicaciones se comporten como se espera. Se realiza desde la perspectiva del usuario final y simula un escenario lo más cercano posible a la realidad.
Hoy en día existen diversas plataformas que nos permiten automatizar los procesos de integración y despliegue para poner una aplicación en producción. En el siguiente ejemplo, veremos la combinación de Cypress, un framework de test E2E, con GitLab CI/CD.
Escribiendo nuestro test E2E
Aquí tenemos un ejemplo de un test E2E escrito con Cypress.
describe('User', () => {
it('can log in', () => {
cy.visit('/')
cy.get('a[href="/login"]').click()
cy.url({ timeout: 2000 }).should('be.equal', 'http://myapp.com/login')
cy.get('input[name="email"]').click().focused().type.('user@mail.com')
cy.get('input[name="password"]').click().focused().type.('user_pass')
cy.intercept('POST', 'http://api.myapp.com/auth/login').as('loginRequest')
cy.get('button[type="submit"]').click()
cy.wait('@loginRequest')
cy.url({ timeout: 2000 }).should('be.equal', 'http://myapp.com/dashboard')
})
})
Estos son los pasos que hace el test anterior, línea por línea:
- Abre la aplicación en la página de inicio.
- Realiza un evento de clic en el elemento ancla que apunta a la página de inicio de sesión.
- Afirma que navegó a la página de inicio de sesión después de 2 segundos para esperar a que se cargue la nueva página.
- Escribe el valor
usuario@mail.com
en el elemento de entrada de correo electrónico presente en la página de inicio de sesión. - Escribe el valor
user_pass
en el elemento de entrada de contraseña presente en la página de inicio de sesión. - Se prepara para interceptar la solicitud que se enviará a la API cuando se envíe el formulario de inicio de sesión.
- Realiza un evento de clic en el botón de envío del formulario de inicio de sesión.
- Espera a que se envíe la solicitud interceptada.
- Afirma que navegó a la página del panel después de 2 segundos para esperar a que se cargue la nueva página, que es el comportamiento esperado para un inicio de sesión exitoso.
Podemos obtener más información sobre Cypress visitando su documentación oficial.
Dockerizando nuestro test E2E
Suponiendo que tenemos nuestra instalación de Cypress con el test End to End anterior en el directorio /e2e
de nuestro proyecto. Veamos cómo creamos contenedores para cada servicio a través de Docker Compose.
services:
database:
image: registry.gitlab.com/company/myapp/database:latest
api:
image: registry.gitlab.com/company/myapp/api:preproduction
depends_on:
- database
client:
image: registry.gitlab.com/company/myapp/client:preproduction
depends_on:
- api
healthcheck:
test: curl --fail http://client || exit 1
interval: 5s
timeout: 5s
retries: 5
e2e:
build:
context: .
dockerfile: Dockerfile.e2e
depends_on:
client:
condition: service_healthy
command: '--quiet --headless --browser chrome'
El archivo Docker Compose anterior crea cuatro contenedores para:
- La base de datos.
- La API.
- La aplicación cliente.
- Cypress con nuestro test E2E.
Cada contenedor depende del anterior para poder ejecutarse. Esto garantiza que el test no se ejecutará antes de que la aplicación cliente esté lista, la aplicación cliente tenga acceso a la API y la API tenga acceso a la base de datos.
El test se ejecutará utilizando el navegador Chrome, en modo headless (sin UI) y omitiendo la verbosidad para un mayor rendimiento del proceso automatizado.
Este es el Dockerfile para el contenedor de Cypress.
FROM cypress/included:13.7.2
WORKDIR /e2e
COPY cypress /e2e/cypress/
COPY cypress.config.js /e2e/
Integrando nuestro test E2E con GitLab CI/CD
Ahora veamos el contenido del archivo .gitlab-ci.yml
presente en la raíz de nuestro proyecto. Este archivo contiene la configuración de nuestro pipeline de CI/CD.
e2e_job:
stage: e2e
tags:
- docker
script:
- bash docker-compose build
- bash docker-compose run --rm e2e
- bash docker-compose down
rules:
- if: '$CI_COMMIT_BRANCH =~ /^feature-|^main$/'
Esto creará una fase llamada e2e
en nuestro pipeline con un job que ejecuta estos tres scripts cada vez que enviamos una confirmación a una rama con el patrón feature-*
o a la rama main
(útil al realizar un merge).
El segundo script ejecutará el contenedor de Cypress, que ejecutará nuestro test E2E. Si el test falla, el job en la fase e2e
también fallará, lo que nos impedirá pasar a la etapa de despliegue y protegerá el entorno.
Para obtener más información sobre GitLab CI/CD, podemos visitar su documentación oficial.
Escrito por Samuel de Vega.