Este checklist de testes MQTT apresenta as doze verificações que pegam a maioria dos incidentes de produção em aplicações MQTT antes que seus usuários os percebam. Cada item vem com um teste rápido que você pode rodar do notebook contra o servidor MQTT público, então no final você terá uma rotina de go-live repetível em vez daquela sensação vaga de que "funcionou na minha mesa".
Por Que Aplicações MQTT Precisam de um Plano de Testes Próprio
Testes unitários cobrem seu parsing e sua lógica de negócio, mas a maioria das falhas de MQTT acontece no espaço entre o client e o broker: um dispositivo que nunca se reinscreve depois de uma reconexão, um dashboard que mostra um valor retido desatualizado, um Last Will que dispara pelo motivo errado ou um payload que de repente tem 70 KB porque alguém adicionou um campo de debug. Nada disso aparece em uma demo do caminho feliz.
A boa notícia é que o comportamento do MQTT é observável. Toda mensagem passa pelo broker, então com dois terminais e um assinante em um wildcard você consegue ver exatamente o que seus dispositivos e serviços fazem. Se precisar relembrar as peças envolvidas, comece por como o MQTT funciona e depois volte aqui.
Monte Primeiro um Ambiente de Testes
Use um ambiente descartável para essas verificações. O servidor MQTT público (gratuito) em broker.connectmq.com, pensado para testes e protótipos, aceita conexões anônimas com qualquer client ID único e não vazio. Escolha um prefixo de topic aleatório para que seus testes não colidam com os de mais ninguém e lembre-se de que a área pública pode ser lida por todos, então nunca envie credenciais reais ou dados de clientes.
# Escolha um prefixo único para esta sessão de testes
export PREFIX="connectmq/demo/$(openssl rand -hex 4)"
echo $PREFIX
# Terminal 1: observe tudo sob o seu prefixo, modo verboso, MQTT 5
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
-i watcher-$RANDOM -t "$PREFIX/#" -v
Mantenha esse observador aberto durante toda a sessão.
Conheça os limites do servidor MQTT público antes de começar, porque algumas verificações os atingem de propósito: 64 KB por mensagem, 10 mensagens por segundo por client, 10 assinaturas por client, 8 níveis de topic e uma expiração de sessão máxima de 30 minutos. Seu broker de produção terá limites diferentes, e é exatamente por isso que você deve testá-los explicitamente.
O Checklist de Testes MQTT
Siga a lista na ordem. Os itens 1 a 4 tratam de conectividade, os itens 5 a 8 de semântica de mensagens e os itens 9 a 12 de robustez.
- Conexão e autenticação. Senha errada, porta errada e falhas de TLS produzem erros claros.
- Unicidade do client ID. Dois clients com o mesmo ID não ficam derrubando um ao outro silenciosamente em loop.
- Reconexão e reinscrição. Após uma queda de rede, o client se reconecta com backoff e restaura suas assinaturas.
- Keep alive. Uma conexão semiaberta é detectada em aproximadamente 1,5 vez o intervalo de keep alive.
- Comportamento de QoS. O QoS que você solicita é o QoS que você recebe, e duplicatas são tratadas.
- Estado retido. Novos assinantes recebem o último valor conhecido correto, e retained messages desatualizadas podem ser removidas.
- Last Will and Testament. Uma desconexão abrupta gera um status offline; um desligamento limpo não.
- Sessões persistentes. Mensagens publicadas enquanto um assinante está offline chegam quando ele volta (apenas QoS 1 e 2).
- Validação de payload. JSON malformado, campos ausentes e tipos errados são rejeitados sem derrubar o consumidor.
- Limites de tamanho, taxa e topic. Payloads grandes demais, rajadas de publicação e topics profundos falham de forma previsível.
- Design de topics e wildcards. As assinaturas correspondem exatamente ao que você pretende e a nada mais.
- Carga e soak. O sistema aguenta quantidades realistas de conexões e taxas de mensagens por horas, não por segundos.
As seções abaixo mostram como executar cada grupo.
Verificações de Conectividade (Itens 1 a 4)
Comece pelos casos negativos. Um bom client registra um motivo significativo quando não consegue se conectar; um ruim fica tentando de novo em silêncio para sempre.
# TCP simples deve funcionar
mosquitto_pub -h broker.connectmq.com -p 1883 -i test-pub-$RANDOM \
-t "$PREFIX/ping" -m "hello"
# TLS na 8883 deve funcionar e validar o certificado 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 sem TLS na porta TLS deve falhar rápido, não travar
mosquitto_pub -h broker.connectmq.com -p 8883 -i test-bad-$RANDOM \
-t "$PREFIX/ping" -m "should fail"
Para o item 2, inicie dois assinantes com o mesmo client ID. O broker desconecta a sessão mais antiga quando a mais nova se conecta. Se os dois clients tiverem reconexão automática, eles vão se revezar derrubando um ao outro, o que aparece nos logs como um padrão rápido de conexão e desconexão. Gere os client IDs a partir de um identificador estável do dispositivo mais uma função, nunca de uma constante fixa compartilhada por toda a frota.
Para o item 3, o teste mais confiável é físico: rode seu client e depois desconecte o cabo de rede ou desative o Wi-Fi por 60 segundos. Quando o link voltar, publique uma mensagem a partir do terminal observador e confirme que seu client ainda a recebe. Muitas bibliotecas se reconectam automaticamente, mas só restauram as assinaturas se você se inscrever dentro do callback de on-connect. O script Python abaixo mostra o padrão e imprime cada mudança de estado para que você veja o que acontece.
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}")
# Inscrever-se aqui faz as assinaturas voltarem após cada reconexão
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)
Com um keep alive de 20 segundos, o broker deve considerar o client desconectado cerca de 30 segundos depois que o tráfego parar. Esse é o item 4: se o seu dispositivo leva vários minutos para perceber um link morto, o keep alive está longo demais ou a biblioteca não está enviando PINGREQ.
Verificações de Semântica de Mensagens (Itens 5 a 8)
O QoS é negociado por assinatura e por publicação, e o nível efetivo de entrega é o menor dos dois. Teste isso explicitamente em vez de presumir. Se não tiver certeza do que cada nível garante, leia antes os níveis de QoS do MQTT explicados.
# Assinar com QoS 1 e publicar com QoS 2: a entrega é rebaixada para 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
A flag -d imprime o fluxo de pacotes (PUBLISH, PUBACK, PUBREC e assim por diante), o que torna o rebaixamento visível. O código do seu consumidor também deve tolerar duplicatas no QoS 1: processe a mesma mensagem duas vezes e confirme que nada quebra, por exemplo usando como chave das gravações um ID de mensagem dentro do payload.
Para o estado retido, publique um valor retido, depois conecte um assinante totalmente novo e confirme que ele o recebe imediatamente com a flag retain ativada. Em seguida, remova-o publicando um payload retido vazio e confirme que o próximo assinante novo não recebe 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
# Remover a retained message
mosquitto_pub -h broker.connectmq.com -i ret-clear-$RANDOM -r -n \
-t "$PREFIX/sensor1/state"
A verificação do Last Will precisa de um client que morra de forma abrupta. Conecte-se com uma mensagem de will e depois mate o processo com kill -9 ou desconecte a rede. O observador deve ver o will depois que o keep alive expirar. Repita com uma saída limpa por Ctrl+C que envie DISCONNECT: o will não pode ser publicado. O guia de Last Will and Testament explica o padrão de status online/offline retido que a maioria das frotas usa.
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 sessões persistentes, conecte um assinante com client ID fixo, QoS 1 e uma expiração de sessão, desconecte-o, publique três mensagens QoS 1 e então reconecte com o mesmo ID. As três devem chegar. No servidor MQTT público, mantenha a expiração de sessão em até 1.800 segundos.
mosquitto_sub -h broker.connectmq.com -V mqttv5 -i persist-fixed-001 \
-c -x 600 -q 1 -t "$PREFIX/queue" -v
Verificações de Robustez (Itens 9 a 12)
Validação de payload deve existir em todo consumidor. Publique lixo de propósito: JSON inválido, um número como string, um payload vazio, uma string de 10 KB em um campo que deveria ser curto. O consumidor deve registrar e ignorar, não travar nem gravar dados sem sentido no banco.
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
Os limites são onde ambientes públicos e de produção mais diferem, então teste o comportamento, não apenas o número. No servidor MQTT público, um payload acima de 64 KB, mais de 10 mensagens por segundo de um mesmo client, uma décima primeira assinatura ou um nono nível de topic devem ser recusados. Garanta que seu client exponha isso como erro e recue, em vez de martelar o broker. No MQTT 5, procure reason codes como 0x97 (quota exceeded) na desconexão ou na confirmação. Os limites de tamanho em um broker MQTT gerenciado dependem do plano; no ConnectMQ, por exemplo, o plano Serverless gratuito permite mensagens de 256 KB e o plano Serverless pago, de 1 MB.
# Payload de 70 KB: deve ser rejeitado no 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 o design de wildcards, assine com o filtro exato que o seu serviço usa e publique em topics que devem e que não devem corresponder. Um filtro como +/+/telemetry costuma corresponder a mais coisas do que o pretendido.
Testes de carga e soak são o último passo. Simule o número real de dispositivos com intervalos e tamanhos de payload realistas e rode por várias horas. Faça isso em um broker privado, não no público, já que o limite de taxa por client do público é baixo de propósito. O panorama de ferramentas de teste de carga MQTT compara as opções.
Tabela de Referência Rápida
| Verificação | Critério de aprovação | Falha típica |
|---|---|---|
| Autenticação e TLS | Erro claro com credenciais ou porta erradas | Nova tentativa infinita e silenciosa |
| Client ID | Uma sessão por dispositivo | Dois dispositivos derrubando um ao outro |
| Reconexão | Assinaturas restauradas automaticamente | Client conectado, mas surdo |
| Keep alive | Link morto detectado em cerca de 1,5x o intervalo | Dispositivo offline por minutos sem ninguém notar |
| QoS | QoS efetivo conforme projetado, duplicatas inofensivas | Eventos contados em dobro |
| Retained | Novo assinante vê o último valor; removível | Valor desatualizado para sempre |
| Last Will | Dispara apenas em falhas | Dispara no desligamento limpo ou nunca |
| Sessões | Mensagens QoS 1 offline entregues | Clean session por acidente |
| Payloads | Entrada inválida ignorada e registrada | Consumidor travado |
| Limites | Rejeição previsível e backoff | Tempestade de novas tentativas |
| Wildcards | Apenas os topics pretendidos correspondem | Vazamento de dados entre tenants ou sites |
| Carga | Memória e latência estáveis por horas | Vazamento lento depois do segundo dia |
Ferramentas Que Aceleram os Testes
Clients de linha de comando são perfeitos para scripts, mas uma ferramenta visual acelera os testes exploratórios. O ConnectMQ oferece um client MQTT no navegador e um explorador de topics ao vivo no portal, além de um explorador MQTT para desktop e uma extensão para VS Code, para que você acompanhe os topics enquanto seus scripts de teste rodam. Seja qual for a ferramenta, salve seus comandos de teste no repositório para que a próxima versão rode o mesmo checklist. Se você é novo no protocolo como um todo, o tutorial de MQTT é o melhor lugar para construir a base da qual essas verificações dependem.
Teste em um Broker ConnectMQ Privado
Depois que as verificações no servidor MQTT público passarem, repita-as no ambiente para o qual você realmente vai entregar. O ConnectMQ oferece um broker privado com TLS na 8883, WebSocket na 8084, cotas por plano e credenciais geradas em poucos cliques. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, substitua YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID e rode o mesmo checklist contra ele antes do go-live.
Perguntas frequentes
O que um checklist de testes MQTT deve incluir?
No mínimo: autenticação e TLS, unicidade do client ID, reconexão com reinscrição, keep alive, QoS, retained messages, Last Will, sessões persistentes, validação de payload, limites do broker, correspondência de wildcards e um teste de carga de várias horas.
Posso testar minha aplicação MQTT no servidor MQTT público?
Sim, para verificações funcionais. Use um client ID e um prefixo de topic únicos e nunca envie dados sensíveis, porque topics públicos podem ser lidos por qualquer pessoa. Rode os testes de carga em um broker privado.
Como testar o Last Will do MQTT sem desconectar o hardware?
Mate o processo do client à força (por exemplo, com kill -9) para que ele não consiga enviar DISCONNECT. O broker publica o will depois que o período de keep alive expira.
Por que meu client para de receber mensagens depois de uma reconexão?
Provavelmente ele se inscreve apenas uma vez na inicialização. Mova as chamadas de subscribe para o callback de on-connect, ou use uma sessão persistente, para que as assinaturas sejam restauradas a cada reconexão.



