Verifica los cuatro estados de tu UI
Solo estás probando uno de los cuatro estados de tu UI. Casi toda pantalla que habla con una red o una base de datos pasa por el mismo ciclo de vida: carga, puede volver vacía, puede fallar y — si todo sale bien — renderiza el éxito. La mayoría de los tests de widgets y componentes verifican exactamente uno de esos cuatro: el render feliz. Eso es 25% de cobertura de los estados que tus usuarios realmente ven.
Por qué el camino feliz no es toda la app
El render de éxito es el estado que miras todo el día mientras desarrollas, así que es el que rara vez se rompe. Los bugs que sufren los usuarios viven en otro lado:
- Un spinner que nunca desaparece porque un error se tragó en silencio.
- Una lista vacía que muestra un vacío blanco en lugar de "Todavía no hay resultados".
- Un estado de error que rompe el componente porque
dataeraundefinedy el render asumía un array. - Un botón de reintentar que no está conectado a nada.
Nada de esto es exótico. Todo esto llega a producción constantemente, porque ningún test puso al componente en ese estado.
Las cuatro verificaciones
| Estado | Qué verificar | Cómo alcanzarlo en un test |
|---|---|---|
| Loading | El spinner/skeleton es visible; el contenido no | Renderizar antes de que la petición mockeada se resuelva |
| Vacío | El mensaje de estado vacío y su CTA se renderizan | Mockear la petición para devolver [] / sin elementos |
| Error | El mensaje de error se renderiza; existe el control de reintento | Mockear la petición para devolver un 500 o un error de red |
| Éxito | Los datos se renderizan; el spinner y el error desaparecieron | Mockear la petición con datos de fixture realistas |
Cuatro estados, cuatro tests. Cada uno son pocas líneas una vez que el mocking de peticiones está listo.
Cómo se ve en código
Con React Testing Library y MSW, el caso de error es un override de un solo handler:
test("handles server error", async () => {
server.use(
http.get("/api/items", () =>
HttpResponse.json({ error: "boom" }, { status: 500 })
)
);
render(<ItemList />);
expect(await screen.findByText(/something went wrong/i)).toBeInTheDocument();
expect(screen.queryByRole("progressbar")).not.toBeInTheDocument();
});
Dos detalles hacen el trabajo pesado:
findBy*espera,queryBy*niega.findByTexthace polling hasta que el estado asíncrono se asienta; quequeryByRole(...)devuelvanulles la forma de verificar que el spinner ya no está. Verificar la ausencia es la mitad del trabajo: una pantalla que muestra un error y un spinner sigue siendo un bug.- Override por test, no por suite.
server.use()de MSW cambia al handler que falla solo para ese test, así el éxito sigue siendo el default y cada estado queda explícito.
La misma forma funciona en todas partes: en Flutter, tester.pumpWidget() más find.byType(CircularProgressIndicator) para el loading, luego avanzas el future con pump y verificas el Text de error; en cualquier stack, el patrón es controla la fuente de datos, verifica el render.
Trucos avanzados
- Convierte los estados en un set de fixtures. Define las respuestas
loading/empty/error/successuna vez y reutilízalas en los tests de cada pantalla. Pantalla nueva, mismos cuatro fixtures. - Dale a cada estado una story de Storybook. Una story por estado significa que diseño revisa las pantallas vacías y de error que de otro modo nadie ve — y las herramientas de regresión visual comparan las cuatro, no solo la de éxito.
- Prueba la transición, no solo el estado. Los bugs más feos son transiciones: error → reintentar → loading → éxito. Un test que hace clic en reintentar después de un fallo mockeado atrapa el botón sin conectar.
- Apunta a tu agente de IA a la tabla. Cuando un agente escribe tests de componentes, "testea este componente" te da el camino feliz. "Escribe cuatro tests: loading, vacío, error, éxito — verifica que el spinner desapareció en los últimos tres" te da cobertura real. La checklist es el prompt.
Recursos
- Async methods — Testing Library (
findBy*,waitFor) - Ejemplo de React Testing Library — tests de éxito y de error de servidor con MSW
- Mocking error responses — documentación de MSW
- Introducción al widget testing — Flutter cookbook
- How to write stories — documentación de Storybook
¿Construyendo una funcionalidad con IA? Yeda AI diseña, audita y entrega sistemas LLM de producción.