Este checklist de pruebas MQTT te guía por las doce comprobaciones que detectan la mayoría de incidencias de producción en aplicaciones MQTT antes de que lo hagan tus usuarios. Cada punto incluye una prueba rápida que puedes ejecutar desde un portátil contra un servidor público, de modo que al final tendrás una rutina repetible para el paso a producción en lugar de la vaga sensación de que "en mi mesa funcionaba".
Por qué las aplicaciones MQTT necesitan su propio plan de pruebas
Las pruebas unitarias cubren el parseo y la lógica de negocio, pero la mayoría de los fallos de MQTT ocurren en el espacio entre el cliente y el broker: un dispositivo que nunca vuelve a suscribirse tras una reconexión, un dashboard que muestra un valor retenido obsoleto, un Last Will que se dispara por el motivo equivocado o un payload que de repente ocupa 70 KB porque alguien añadió un campo de depuración. Nada de esto aparece en una demo del camino feliz.
La buena noticia es que el comportamiento de MQTT es observable. Cada mensaje pasa por el broker, así que con dos terminales y un suscriptor con comodín puedes ver exactamente qué hacen tus dispositivos y servicios. Si necesitas refrescar las piezas, empieza por cómo funciona MQTT y vuelve aquí.
Primero, prepara un entorno de pruebas
Usa un entorno desechable para estas comprobaciones. El servidor MQTT público gratuito broker.connectmq.com, pensado para pruebas y prototipos y no para datos de producción, acepta conexiones anónimas con cualquier client ID único y no vacío. Elige un prefijo de topic aleatorio para que tus pruebas no choquen con las de nadie, y recuerda que el área pública es legible por cualquiera, así que nunca envíes credenciales reales ni datos de clientes.
# Elige un prefijo único para esta sesión de pruebas
export PREFIX="connectmq/demo/$(openssl rand -hex 4)"
echo $PREFIX
# Terminal 1: observa todo bajo tu prefijo, en modo detallado, MQTT 5
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
-i watcher-$RANDOM -t "$PREFIX/#" -v
Mantén ese observador abierto durante toda la sesión.
Conoce los límites del servidor público antes de empezar, porque algunas comprobaciones los alcanzan a propósito: 64 KB por mensaje, 10 mensajes por segundo por cliente, 10 suscripciones por cliente, 8 niveles de topic y una expiración de sesión máxima de 30 minutos. Tu broker de producción tendrá límites distintos, y precisamente por eso debes probarlos de forma explícita.
El checklist de pruebas MQTT
Recorre la lista en orden. Los puntos 1 a 4 tratan de la conectividad, del 5 al 8 de la semántica de los mensajes y del 9 al 12 de la robustez.
- Conexión y autenticación. Una contraseña errónea, un puerto equivocado y los fallos de TLS producen errores claros.
- Unicidad del client ID. Dos clientes con el mismo ID no se expulsan mutuamente en un bucle silencioso.
- Reconexión y resuscripción. Tras una caída de red, el cliente se reconecta con backoff y restaura sus suscripciones.
- Keep alive. Una conexión semiabierta se detecta en aproximadamente 1,5 veces el intervalo de keep alive.
- Comportamiento del QoS. El QoS que pides es el QoS que obtienes, y los duplicados se gestionan.
- Estado retenido. Los nuevos suscriptores reciben el último valor conocido correcto, y los mensajes retenidos obsoletos se pueden borrar.
- Last Will and Testament. Una desconexión abrupta produce un estado offline; un apagado limpio, no.
- Sesiones persistentes. Los mensajes publicados mientras un suscriptor está offline llegan cuando vuelve (solo QoS 1 y 2).
- Validación de payloads. El JSON mal formado, los campos que faltan y los tipos incorrectos se rechazan sin que el consumidor se caiga.
- Límites de tamaño, tasa y topics. Los payloads demasiado grandes, las ráfagas de publicaciones y los topics muy profundos fallan de forma predecible.
- Diseño de topics y comodines. Las suscripciones coinciden exactamente con lo que pretendes y nada más.
- Carga y resistencia (soak). El sistema aguanta un número realista de conexiones y tasas de mensajes durante horas, no segundos.
Las secciones siguientes muestran cómo ejecutar cada grupo.
Comprobaciones de conectividad (puntos 1 a 4)
Empieza por los casos negativos. Un buen cliente registra un motivo útil cuando no puede conectarse; uno malo reintenta en silencio para siempre.
# TCP sin cifrar debería funcionar
mosquitto_pub -h broker.connectmq.com -p 1883 -i test-pub-$RANDOM \
-t "$PREFIX/ping" -m "hello"
# TLS en 8883 debería funcionar y validar el certificado de Let's Encrypt
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-i test-tls-$RANDOM -t "$PREFIX/ping" -m "hello over tls"
# MQTT sin cifrar contra el puerto TLS debería fallar rápido, no quedarse colgado
mosquitto_pub -h broker.connectmq.com -p 8883 -i test-bad-$RANDOM \
-t "$PREFIX/ping" -m "should fail"
Para el punto 2, arranca dos suscriptores con el mismo client ID. El broker desconecta la sesión más antigua cuando se conecta la nueva. Si ambos clientes se reconectan automáticamente, se irán expulsando por turnos, lo que se ve en los logs como un patrón rápido de conexiones y desconexiones. Genera los client IDs a partir de un identificador estable del dispositivo más un rol, nunca a partir de una constante fija compartida por toda la flota.
Para el punto 3, la prueba más fiable es física: ejecuta tu cliente y desenchufa el cable de red o desactiva el Wi-Fi durante 60 segundos. Cuando vuelva el enlace, publica un mensaje desde la terminal del observador y confirma que tu cliente sigue recibiéndolo. Muchas bibliotecas se reconectan automáticamente, pero solo restauran las suscripciones si te suscribes dentro del callback de conexión. El script de Python siguiente muestra el patrón e imprime cada cambio de estado para que veas lo que ocurre.
import time
import uuid
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/replace-me"
client_id = f"reconnect-test-{uuid.uuid4().hex[:8]}"
def on_connect(client, userdata, flags, reason_code, properties):
print(f"{time.strftime('%X')} connected: {reason_code}")
# Suscribirse aquí hace que las suscripciones vuelvan tras cada reconexión
client.subscribe(f"{PREFIX}/cmd/#", qos=1)
def on_disconnect(client, userdata, disconnect_flags, reason_code, properties):
print(f"{time.strftime('%X')} disconnected: {reason_code}")
def on_message(client, userdata, msg):
print(f"{time.strftime('%X')} {msg.topic} qos={msg.qos} retain={msg.retain} {msg.payload!r}")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=client_id,
protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.reconnect_delay_set(min_delay=1, max_delay=30)
client.connect("broker.connectmq.com", 1883, keepalive=20)
client.loop_forever(retry_first_connection=True)
Con un keep alive de 20 segundos, el broker debería dar por desaparecido al cliente unos 30 segundos después de que se detenga el tráfico. Ese es el punto 4: si tu dispositivo tarda varios minutos en notar un enlace muerto, tu keep alive es demasiado largo o la biblioteca no está enviando PINGREQ.
Comprobaciones de semántica de mensajes (puntos 5 a 8)
El QoS se negocia por suscripción y por publicación, y el nivel de entrega efectivo es el menor de los dos. Pruébalo explícitamente en lugar de darlo por hecho. Si no tienes claro qué garantiza cada nivel, lee primero niveles de QoS de MQTT explicados.
# Suscripción con QoS 1, publicación con QoS 2: la entrega se rebaja a QoS 1
mosquitto_sub -h broker.connectmq.com -i qos-sub-$RANDOM -q 1 \
-t "$PREFIX/qos" -v -d
mosquitto_pub -h broker.connectmq.com -i qos-pub-$RANDOM -q 2 \
-t "$PREFIX/qos" -m "qos test" -d
El flag -d imprime el flujo de paquetes (PUBLISH, PUBACK, PUBREC, etc.), lo que hace visible la rebaja. Tu código consumidor también debe tolerar duplicados con QoS 1: procesa el mismo mensaje dos veces y confirma que nada se rompe, por ejemplo usando como clave de escritura un ID de mensaje incluido en el payload.
Para el estado retenido, publica un valor retenido, conecta un suscriptor completamente nuevo y confirma que lo recibe de inmediato con el flag retain activado. Después bórralo publicando un payload retenido vacío y confirma que el siguiente suscriptor nuevo no recibe nada.
mosquitto_pub -h broker.connectmq.com -i ret-$RANDOM -r \
-t "$PREFIX/sensor1/state" -m '{"temp":21.4}'
mosquitto_sub -h broker.connectmq.com -i ret-check-$RANDOM \
-t "$PREFIX/sensor1/state" -v -C 1 -W 5
# Borra el mensaje retenido
mosquitto_pub -h broker.connectmq.com -i ret-clear-$RANDOM -r -n \
-t "$PREFIX/sensor1/state"
La comprobación del Last Will necesita un cliente que muera de forma abrupta. Conéctate con un mensaje will y mata el proceso con kill -9 o desconecta la red. El observador debería ver el will cuando expire el keep alive. Repite con una salida limpia con Ctrl+C que envíe DISCONNECT: el will no debe publicarse. La guía de Last Will and Testament explica el patrón de estado online/offline retenido que usan la mayoría de flotas.
mosquitto_sub -h broker.connectmq.com -i lwt-dev-$RANDOM -k 10 \
--will-topic "$PREFIX/dev1/status" --will-payload offline --will-retain \
-t "$PREFIX/dev1/cmd"
Para las sesiones persistentes, conecta un suscriptor con un client ID fijo, QoS 1 y una expiración de sesión, desconéctalo, publica tres mensajes con QoS 1 y vuelve a conectarte con el mismo ID. Deberían llegar los tres. En el broker público, mantén la expiración de sesión en 1.800 segundos o menos.
mosquitto_sub -h broker.connectmq.com -V mqttv5 -i persist-fixed-001 \
-c -x 600 -q 1 -t "$PREFIX/queue" -v
Comprobaciones de robustez (puntos 9 a 12)
La validación de payloads debe estar en todo consumidor. Publica basura a propósito: JSON no válido, un número como cadena, un payload vacío, una cadena de 10 KB en un campo que esperas corto. El consumidor debe registrarlo y saltárselo, no caerse ni escribir disparates en la base de datos.
for p in '{"temp":' '{"temp":"hot"}' '' '{"unexpected":true}'; do
mosquitto_pub -h broker.connectmq.com -i bad-$RANDOM \
-t "$PREFIX/sensor1/telemetry" -m "$p"
done
Los límites son donde más difieren los entornos públicos y los de producción, así que prueba el comportamiento, no solo la cifra. En el broker público, un payload de más de 64 KB, más de 10 mensajes por segundo desde un mismo cliente, una undécima suscripción o un noveno nivel de topic deberían ser rechazados. Asegúrate de que tu cliente lo muestra como un error y aplica backoff en lugar de bombardear al broker. En MQTT 5, busca reason codes como 0x97 (cuota superada) en la desconexión o en la confirmación. Los límites de tamaño en un broker MQTT gestionado dependen del plan; en ConnectMQ, por ejemplo, el plan Serverless gratuito permite mensajes de 256 KB y el plan Serverless de pago, de 1 MB.
# Payload de 70 KB: debería rechazarse en el broker público
head -c 71680 /dev/urandom | base64 > /tmp/big.txt
mosquitto_pub -h broker.connectmq.com -V mqttv5 -i big-$RANDOM \
-t "$PREFIX/big" -f /tmp/big.txt -d
Para el diseño de comodines, suscríbete con el filtro exacto que usa tu servicio y publica en topics que deberían coincidir y en otros que no. Un filtro como +/+/telemetry suele coincidir con más de lo previsto.
Las pruebas de carga y resistencia son el último paso. Simula el número real de dispositivos con intervalos y tamaños de payload realistas, y déjalo funcionando varias horas. Hazlo contra un broker privado y no contra el público, ya que el límite de tasa por cliente del público es deliberadamente bajo. La recopilación de herramientas de pruebas de carga MQTT compara las opciones.
Tabla de referencia rápida
| Comprobación | Criterio de éxito | Fallo típico |
|---|---|---|
| Autenticación y TLS | Error claro con credenciales o puerto incorrectos | Reintento infinito silencioso |
| Client ID | Una sesión por dispositivo | Dos dispositivos expulsándose mutuamente |
| Reconexión | Suscripciones restauradas automáticamente | Cliente conectado pero sordo |
| Keep alive | Enlace muerto detectado en unas 1,5 veces el intervalo | Dispositivo offline durante minutos sin que nadie lo note |
| QoS | QoS efectivo según el diseño, duplicados inofensivos | Eventos contados dos veces |
| Retenidos | El nuevo suscriptor ve el último valor; se puede borrar | Valor obsoleto para siempre |
| Last Will | Se dispara solo ante una caída | Se dispara en apagados limpios o nunca |
| Sesiones | Mensajes QoS 1 offline entregados | Clean session por accidente |
| Payloads | Entrada incorrecta descartada y registrada | Caída del consumidor |
| Límites | Rechazo predecible y backoff | Tormenta de reintentos |
| Comodines | Solo coinciden los topics previstos | Fuga de datos entre clientes o sedes |
| Carga | Memoria y latencia estables durante horas | Fuga lenta a partir del segundo día |
Herramientas que agilizan las pruebas
Los clientes de línea de comandos son perfectos para scripts, pero una herramienta visual acelera las pruebas exploratorias. ConnectMQ incluye en el portal un cliente MQTT en el navegador y un explorador de topics en vivo, además de un explorador MQTT de escritorio y una extensión para VS Code, para que puedas observar los topics mientras se ejecutan tus scripts de prueba. Uses lo que uses, guarda tus comandos de prueba en el repositorio para que la siguiente versión pase el mismo checklist. Si el protocolo en general es nuevo para ti, el tutorial de MQTT es el mejor lugar para construir la base en la que se apoyan estas comprobaciones.
Prueba en un broker privado de ConnectMQ
Cuando pasen las comprobaciones en el broker público, repítelas en el entorno al que realmente vas a desplegar. ConnectMQ, como broker MQTT gestionado, te da en unos pocos clics un broker privado con TLS en el 8883, WebSocket en el 8084, cuotas por plan y credenciales generadas. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, sustituye YOUR_USERNAME, YOUR_PASSWORD y YOUR_CLIENT_ID y ejecuta contra él el mismo checklist antes del paso a producción.
Preguntas frecuentes
¿Qué debe incluir un checklist de pruebas MQTT?
Como mínimo: autenticación y TLS, unicidad del client ID, reconexión con resuscripción, keep alive, QoS, mensajes retenidos, Last Will, sesiones persistentes, validación de payloads, límites del broker, coincidencia de comodines y una prueba de carga de varias horas.
¿Puedo probar mi aplicación MQTT en un broker público?
Sí, para las comprobaciones funcionales. Usa un client ID y un prefijo de topic únicos y nunca envíes datos sensibles, porque los topics públicos son legibles por cualquiera. Haz las pruebas de carga en un broker privado.
¿Cómo pruebo el Last Will de MQTT sin desenchufar hardware?
Mata el proceso del cliente de forma brusca (por ejemplo con kill -9) para que no pueda enviar DISCONNECT. El broker publica el will cuando expira el periodo de keep alive.
¿Por qué mi cliente deja de recibir mensajes tras una reconexión?
Probablemente solo se suscribe una vez al arrancar. Mueve las llamadas de suscripción al callback de conexión, o usa una sesión persistente, para que las suscripciones se restauren en cada reconexión.



