---
title: "Prueba los píxeles: control de calidad por capturas para un equipo pequeño"
description: "Nuestra batería de pruebas estaba en verde y el desplegable no se podía pulsar. Las pruebas unitarias no ven fallos de apilamiento, ni un tema oscuro roto, ni desbordes en móvil. Este es el pequeño montaje de capturas que ahora mira por nosotros todas las pantallas, y los fallos visuales que caza y que las pruebas nunca cazarán."
url: "https://bookatu.com/es-es/blog/test-the-pixels-screenshot-driven-qa"
language: "es"
section: "Blog"
category: "Ingeniería"
author: "El equipo de ingeniería de Bookatu"
published: "2026-07-11"
updated: "2026-07-11"
tags: ["pruebas de regresión visual", "capturas con playwright", "pruebas en navegador headless", "probar el modo oscuro", "automatización de qa"]
---

# Prueba los píxeles: control de calidad por capturas para un equipo pequeño

Nuestra batería de pruebas estaba en verde y el desplegable no se podía pulsar. Las pruebas unitarias no ven fallos de apilamiento, ni un tema oscuro roto, ni desbordes en móvil. Este es el pequeño montaje de capturas que ahora mira por nosotros todas las pantallas, y los fallos visuales que caza y que las pruebas nunca cazarán.

> **La versión corta**
>
> - Unas pruebas en verde demuestran que la lógica funciona. No dicen nada sobre si una persona puede ver el resultado o pulsarlo.
> - Un montaje de capturas es pequeño: un entorno local con datos generados, un inicio de sesión guardado y un bucle sobre páginas, temas y tamaños de pantalla.
> - Acompaña las imágenes con comprobaciones programáticas: elementFromPoint demuestra que un botón se puede pulsar y getBoundingClientRect demuestra que un campo cabe en la pantalla.
> - Y después mira las capturas de verdad. Mirarlas es la prueba.

Lo adoptamos por las malas: después de lanzar regresiones visuales que una sola captura habría cazado. Un panel esmerilado que salía pálido sobre fondos oscuros. Un menú que se dibujaba pero no se podía pulsar. Un campo de búsqueda que a lo ancho de un móvil existía como una tira de 65 píxeles. Todos pasaron una batería de pruebas en verde, porque la batería probaba funciones y los fallos vivían en los píxeles.

## El montaje es más pequeño de lo que crees

El nuestro es un entorno local lleno de datos falsos convincentes, un inicio de sesión sin interfaz cuya sesión se guarda en disco para que nada lo frene y un bucle: páginas por temas por tamaños de pantalla. Escritorio y móvil, claro y oscuro, todas las pantallas que importan. Todo cabe en un script corto, y un barrido completo produce una carpeta de imágenes en unos minutos.

```js
import { chromium } from 'playwright';

const browser = await chromium.launch();
const ctx = await browser.newContext({
  storageState: 'auth.json', // login once, reuse everywhere
  viewport: { width: 1440, height: 900 },
});
const page = await ctx.newPage();

for (const [name, url] of PAGES) {
  await page.goto(BASE + url, { waitUntil: 'load' });
  for (const theme of ['light', 'dark']) {
    await page.evaluate((t) =>
      document.documentElement.setAttribute('data-theme', t), theme);
    await page.screenshot({ path: `shots/${name}-${theme}.png`, fullPage: true });
  }
}
```

## Capturas más pruebas

Las imágenes cazan lo que cazan los ojos. Para los fallos de interacción quieres que declare el navegador. Dos líneas hacen casi todo el trabajo: elementFromPoint en el centro de un control te dice qué recibiría realmente el clic, y getBoundingClientRect te dice si el control cabe de verdad en el tamaño de pantalla que dice soportar. Ahora comprobamos las dos cosas en todo lo que nos ha quemado alguna vez.

```js
// Is the menu item really clickable, or is something invisible covering it?
const hit = await page.evaluate(() => {
  const el = document.querySelector('[role="menuitem"]');
  const r = el.getBoundingClientRect();
  const top = document.elementFromPoint(r.x + r.width / 2, r.y + r.height / 2);
  return el === top || el.contains(top);
});

// Does the search input actually fit a 390px phone?
const fits = await page.evaluate(() => {
  const r = document.querySelector('input[name="q"]').getBoundingClientRect();
  return r.right <= window.innerWidth && r.width > 200;
});
```

## Los dos temas, siempre

Los fallos de modo oscuro son una categoría aparte porque se esconden de quien trabaja siempre en un solo tema. Un relleno casi blanco escrito a mano parece intencionado en una página clara y radiactivo en una oscura. Cambiar el atributo del tema dentro de la misma visita cuesta una línea y duplica tu cobertura. Damos por no probada cualquier pantalla que no se haya fotografiado en los dos temas.

![Un panel de reservas fotografiado en tema claro](https://bookatu.com/blog/shots/dashboard-light.png)

*La misma página, fotografiada dos veces por barrido. Clara...*

![El mismo panel de reservas fotografiado en tema oscuro](https://bookatu.com/blog/shots/dashboard-dark.png)

*...y oscura. Los colores escritos a mano no tienen dónde esconderse cuando existen los dos fotogramas.*

## Qué caza

- Fallos de contexto de apilamiento: dibujado, visible y sin poder pulsarse. Esto solo lo ve una prueba de impacto.
- Fugas de tema: superficies claras brillando en páginas oscuras, gráficos que desaparecen, ilustraciones con el fondo incrustado.
- Desbordes en móvil: barras fijas tapando el contenido, campos recortados a una tira, titulares cortados a media frase.
- Textos en su contexto: el recorte, la contradicción, la frase que ningún linter va a señalar.

Nada de esto sustituye a la batería de pruebas unitarias. La batería demuestra que las cuentas del dinero salen; las capturas demuestran que una persona puede llegar al botón que las dispara. Un equipo pequeño no tiene departamento de calidad, pero una carpeta de capturas recientes revisadas antes de cada lanzamiento es una imitación bastante decente. La prueba es mirarlas.

> Las pruebas pasan es una afirmación sobre tus funciones. La captura es una afirmación sobre tu producto.
