Test E2E en Python con Playwright

Hace unos días tuve que configurar Playwright para ejecutar unos tests E2E en Python y me dio bastante dolor de cabeza. Así que para que no me pase más, hoy os cuento como lo hice.

¿Qué es Playwright?

Playwright es una librería de testing pensada para hacer pruebas end-to-end en las que es necesario el uso de un navegador. Si llevas tiempo en el mundo del desarrollo es fácil que te hayas cruzado con Cypress, pues Playwright viene a ser la competencia.

Últimamente además desde Cypress se están tomando algunas decisiones bastante controvertidas, dejo por aquí un hilo muy bueno de Estefanía donde lo explica todo super detallado.

Python Playwright

Lo interesante de Playwright es que tiene su librería disponible en Python lo que la hace muy interesante si estás trabajando en un proyecto donde todo el código esta escrito en este lenguaje. De esta forma los tests E2E tienen la misma forma que el resto de tests de nuestra app, lo que hace que sea mucho más fácil de mantener por todo el equipo.

Mirando su documentación no parece bastante difícil de echarlo a andar, básicamente necesitamos instalar pytest-playwright que es un plugin de Pytest:

pip install pytest-playwright

Una vez que tenemos disponible el plugin necesitamos instalar playwright y sus dependencias, entre otras muchas cosas se necesita instalar los navegadores para usarlos en los tests:

playwright install

Con estas dos dependencias instaladas bastaría crear un test y ejecutarlo con pytest:

import re
from playwright.sync_api import Page, expect

def test_has_title(page: Page):
    page.goto("https://pmareke.com/")

    expect(page).to_have_title(re.compile("pmareke"))

def test_get_started_link(page: Page):
    page.goto("https://pmareke.com")

    page.get_by_role("link", name="Links").click()

    expect(page.get_by_text("Booker")).to_be_visible()

En mi caso no fue así, ya que estoy usando Poetry como gestor de dependencias y Playwright no se estaba instalando dentro del entorno virtual por alguna razón que aún desconozco.

Aun asumiendo que la instalación de Playwright fuera correctame existe una forma más limpia y sencilla de ejecutar nuestros tests E2E.

Recomendación de uso

Como decía, para mí existe una forma mucho más sencilla de usar Playwright como runner de nuestros tests E2E y es tan simple como hacer uso de Docker.

Por suerte para nosotros la propia librería nos proporciona una imagen donde ya están instaladas todas las dependencias que Playwright necesita y solamente hace falta instalar pytest y sus plugins:

FROM mcr.microsoft.com/playwright/python

RUN pip3 install --no-cache-dir pytest pytest-playwright pytest-xdist

WORKDIR /code

COPY tests .

CMD pytest -n auto -ra

Como podemos ver en el Dockerfile además es necesario realizar estas 3 acciones:

  • Indicar que nuestro directorio de trabajo es una carpeta llamada code.
  • Copiar nuestros tests dentro de la imagen.
  • Ejecutar pytest.
    • Los flags -n y -ra son para usar paralelismo y mostrar errores solo en los tests fallidos respectivamente.

Una vez completado el Dockerfile solo nos quedaría ejecutar los tests usando Docker directamente.

En mi caso me gusta usar siempre un Makefile que me ayude a ejecutar los tests.

.DEFAULT_GOAL := help

.PHONY: help
help:  ## Show this help.
	@grep -E '^\S+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | \
		awk 'BEGIN {FS = ":.*?## "}; {printf "%-30s %s\n", $$1, $$2}'

.PHONY: test
test: ## Run Playwright tests
	docker build . -t playwright
	docker run --rm playwright

De esta forma podemos ejecutar make test en nuestra terminal y los tests deberían ejecutarse correctamente:

docker build . -t playwright
[+] Building 2.1s (9/9) FINISHED                                               docker:desktop-linux
 => [internal] load .dockerignore                                                              0.0s

...

docker run --rm playwright
============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.4.3, pluggy-1.3.0
rootdir: /code
plugins: xdist-3.4.0, base-url-2.0.0, playwright-0.4.3
created: 8/8 workers
8 workers [2 items]

..                                                                       [100%]
============================== 2 passed in 1.47s ===============================

Fácil y para todos los públicos. ¡Espero que os haya gustado, dejo por aquí un repositorio para verlo con más calma!