O maior portal de MU Online do Brasil — desde 2003
Tutorial Avançado Servidor

Como automatizar testes de regressão no servidor de MU Online

Crie uma suíte de testes de regressão automatizados para validar que atualizações de configuração, eventos e itens do seu servidor de MU Online não quebram funcionalidades que já funcionavam antes.

GA Gabriel · Atualizado em 17 abr 2026 · ⏱ 16 min de leitura
Resposta rápida

Cada atualização em um servidor de MU Online — uma nova season, um evento customizado, um ajuste de taxa de drop, uma correção de bug — carrega o risco de quebrar algo que já funcionava. É extremamente comum ver um servidor lançar uma correção pontual e, sem perceber, derrubar a Chaos Machine ou imp

Cada atualização em um servidor de MU Online — uma nova season, um evento customizado, um ajuste de taxa de drop, uma correção de bug — carrega o risco de quebrar algo que já funcionava. É extremamente comum ver um servidor lançar uma correção pontual e, sem perceber, derrubar a Chaos Machine ou impedir login em uma classe específica, só descobrindo o problema pelos jogadores reclamando no Discord. Este tutorial mostra como montar uma suíte de testes de regressão automatizados que roda antes de qualquer atualização ir para produção, cobrindo os fluxos mais críticos do servidor: login, criação de personagem, drop, Chaos Machine e eventos.

Por que testes de regressão importam tanto em servidores privados

Diferente de um software comum, um servidor de MU Online tem uma característica particular: as "regras de negócio" vivem espalhadas entre arquivos de configuração (.txt, .xml, .ini), scripts de evento, banco de dados e o próprio binário do emulador. Uma mudança pequena em um arquivo de configuração pode ter efeito colateral em um sistema aparentemente não relacionado — por exemplo, alterar a taxa de drop de um monstro pode, por erro de digitação, zerar o drop de outro item na mesma linha. Testes de regressão automatizados existem justamente para pegar esse tipo de efeito colateral antes que chegue aos jogadores.

Definindo o escopo mínimo viável da suíte

Não é necessário (nem realista) testar tudo desde o início. Priorize pelos fluxos que, se quebrarem, geram o maior volume de reclamações e maior dano à reputação do servidor:

Fluxo críticoPor que priorizarFrequência de regressão
Login e criação de personagemBloqueia 100% dos jogadores se quebrarAlta (qualquer mudança de conta/char)
Drop básico de itensAfeta a economia inteira do servidorMédia-alta (mudanças de configuração de monstro)
Chaos Machine (criação/combinação)Item mais usado no endgameMédia (mudanças em receitas)
Entrada em eventos (BC, DS, CC)Afeta engajamento diárioMédia (mudanças de script de evento)
Sistema de sockets/Seed SpheresAfeta itens de topo de progressãoBaixa, mas crítica quando ocorre
Loja/cash shopAfeta receita diretaAlta (qualquer mudança de preço/item)

Arquitetura da suíte de testes

O desenho recomendado separa os testes em camadas, do mais rápido/barato ao mais lento/caro, para rodar os baratos com frequência e os caros apenas antes de releases:

CamadaO que validaCusto de execução
Testes de configuraçãoSintaxe e consistência dos arquivos .txt/.xmlSegundos
Testes de banco de dadosIntegridade de schema e dados de referênciaSegundos a minutos
Testes de protocolo/GM commandFluxos via comandos administrativos (sem cliente gráfico)Minutos
Testes end-to-end (cliente real/bot)Fluxo completo como o jogador viveMinutos a dezenas de minutos

Testes de configuração (validação de sintaxe e consistência)

A camada mais barata e mais valiosa: um script que valida se os arquivos de configuração ainda têm o número de colunas esperado e se valores críticos não ficaram fora de faixa, antes mesmo de subir o servidor:

import csv

def validar_item_txt(caminho, colunas_esperadas=25):
    erros = []
    with open(caminho, encoding='latin-1') as f:
        for i, linha in enumerate(f, 1):
            if linha.strip().startswith('//') or not linha.strip():
                continue
            campos = linha.split('\t')
            if len(campos) != colunas_esperadas:
                erros.append(f"Linha {i}: {len(campos)} colunas, esperado {colunas_esperadas}")
    return erros

erros = validar_item_txt("Data/Item/Item.txt")
if erros:
    print(f"FALHA: {len(erros)} inconsistências encontradas")
    for e in erros[:10]:
        print(e)
else:
    print("OK: Item.txt consistente")

Testes de banco de dados (schema e dados de referência)

Depois de uma migração ou atualização de emulador, é comum uma tabela perder uma coluna ou um valor de referência mudar sem ninguém notar. Um teste simples de schema:

-- Verifica se colunas críticas ainda existem após uma migração
SELECT COUNT(*) AS colunas_encontradas
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Character'
  AND COLUMN_NAME IN ('Strength', 'Dexterity', 'Vitality', 'Energy', 'Level');
-- Esperado: 5
-- Verifica se os dados de referência de classe/mapa não foram corrompidos
SELECT COUNT(*) FROM MapInfo WHERE MapNumber BETWEEN 0 AND 10;
-- Esperado: um número conhecido e estável

Testes via GM command (sem precisar do cliente gráfico)

Muitos emuladores expõem comandos administrativos via console do servidor ou via chat de GM que permitem testar fluxos sem abrir o cliente completo — útil para automação em CI:

# Pseudocódigo de teste via comando de GM (adaptar ao protocolo real do emulador)
def testar_criacao_item(conexao_gm, tipo, indice, nivel):
    resposta = conexao_gm.enviar_comando(f"/make {tipo} {indice} {nivel}")
    assert "criado" in resposta.lower(), f"Falha ao criar item {tipo}:{indice} — resposta: {resposta}"

def testar_drop_monstro(conexao_gm, monstro_id):
    resposta = conexao_gm.enviar_comando(f"/killmob {monstro_id}")
    # Valida no log/banco se algum drop foi gerado

Testes end-to-end com bot simulando o jogador

Para os fluxos mais críticos (login, criação de personagem, entrada em evento), vale ter um bot que efetivamente conecta e joga um roteiro fixo, validando o resultado esperado em cada etapa:

def teste_login_e_criacao_char(conta_teste, senha_teste):
    cliente = ClienteMuTeste(host="staging.meuservidor.com", porta=44405)
    assert cliente.login(conta_teste, senha_teste), "Login falhou"
    assert cliente.criar_personagem("TesteQA01", classe="DarkKnight"), "Criação de personagem falhou"
    assert cliente.entrar_no_jogo(), "Falha ao entrar no mundo com o personagem criado"
    cliente.desconectar()

Mantenha uma conta de teste dedicada (qa_bot_01) separada de contas reais, resetada a cada execução para não acumular estado entre testes.

Testando o fluxo da Chaos Machine

Como a Chaos Machine é um dos fluxos mais sensíveis a mudanças de configuração (receitas, taxa de sucesso), vale um teste dedicado que gera os itens de entrada via GM, tenta a combinação e valida o resultado:

def teste_chaos_machine(conexao_gm, receita_id, itens_entrada):
    for item in itens_entrada:
        conexao_gm.enviar_comando(f"/make {item['tipo']} {item['indice']} {item['nivel']}")
    resultado = conexao_gm.enviar_comando(f"/testarcombinacao {receita_id}")
    assert resultado in ("sucesso", "falha_esperada"), f"Resultado inesperado: {resultado}"

Testando entrada em eventos automaticamente

Reaproveitando a lógica de leitura de estado de evento (já usada no pipeline de anúncio automático), é possível validar que o NPC de entrada do evento realmente move o personagem de teste para o mapa correto:

def teste_entrada_devil_square(cliente_teste):
    cliente_teste.falar_com_npc("Devil Messenger")
    cliente_teste.selecionar_opcao("Entrar no Devil Square")
    mapa_atual = cliente_teste.obter_mapa_atual()
    assert mapa_atual == "Devias 2 (Evento)", f"Esperado Devias 2, obtido {mapa_atual}"

Integrando a suíte a um pipeline de CI

O maior ganho vem de rodar a suíte automaticamente sempre que uma configuração é alterada em staging, antes de promover para produção. Um pipeline simples baseado em script, sem depender de infraestrutura complexa de CI:

#!/bin/bash
set -e
echo "1. Validando arquivos de configuração..."
python3 testes/validar_configs.py

echo "2. Validando schema do banco..."
mysql -u teste -p"$DB_PASS" mu_staging < testes/validar_schema.sql

echo "3. Rodando testes via GM command..."
python3 testes/testes_gm.py

echo "4. Rodando testes end-to-end..."
python3 testes/testes_e2e.py

echo "Suíte de regressão concluída com sucesso. Liberado para produção."

Se qualquer etapa falhar (set -e interrompe o script no primeiro erro), a promoção para produção deve ser bloqueada manualmente até a causa ser corrigida.

Mantendo um changelog de regressões encontradas

Toda falha pega pela suíte (ou, pior, escapada dela) deve ser documentada: o que quebrou, por que, e o que foi corrigido. Isso evita que o mesmo bug reapareça silenciosamente em uma atualização futura, e ajuda a priorizar quais novos testes adicionar à suíte:

DataMudança que causouSintomaCorreçãoTeste adicionado depois
2026-06-10Ajuste de drop de monstroItem X parou de droparCorrigido índice na linha erradaTeste de drop por monstro
2026-07-02Atualização de emuladorChaos Machine travavaReceita desatualizada no config novoTeste de combinação automatizado

Erros comuns e soluções

SintomaCausa provávelSolução
Suíte não pega a regressão realEscopo de testes limitado aos fluxos erradosPriorize os fluxos de maior impacto (login, drop, Chaos Machine)
Testes end-to-end são muito lentosSuíte roda tudo a cada pequena mudançaSepare camadas rápidas (config/schema) das lentas (e2e), rode e2e só antes de release
Conta de teste acumula itens/estado entre execuçõesFalta de reset/limpeza pós-testeRecrie/limpe a conta de teste no início de cada execução
Testes passam em staging mas quebra em produçãoAmbientes com configuração divergenteSincronize configs entre staging e produção antes de cada teste
Ninguém revisa as falhas da suíteAusência de processo/responsável definidoDefina um dono da suíte e trate falha como bloqueador de release
Regressão do mesmo tipo se repeteFalha não documentada, teste não adicionado depoisMantenha o changelog de regressões e adicione teste específico após cada uma

Checklist de testes de regressão

  • Escopo mínimo de fluxos críticos definido e priorizado.
  • Testes de configuração (sintaxe/consistência) implementados.
  • Testes de schema/dados de referência do banco implementados.
  • Testes via GM command cobrindo criação de item e drop.
  • Teste end-to-end de login e criação de personagem funcionando.
  • Teste da Chaos Machine e de entrada em eventos automatizado.
  • Pipeline de execução (script/CI) rodando antes de cada promoção para produção.
  • Changelog de regressões encontradas mantido e revisado.

Com a suíte de regressão rodando antes de cada atualização, você troca o "torcer para não ter quebrado nada" por confirmação real antes de expor a mudança aos jogadores. Se o seu servidor ainda não tem um ambiente de staging separado da produção, esse é o próximo passo natural — revise o tutorial de criação de servidor de MU Online para estruturar essa separação corretamente.

Perguntas frequentes

O que é exatamente um teste de regressão nesse contexto?

É um teste que confirma que uma funcionalidade que já funcionava (login, drop de item, criação na Chaos Machine, entrada em evento) continua funcionando depois de uma mudança de configuração, atualização de emulador ou correção de bug. O objetivo é pegar quebras não intencionais antes dos jogadores.

Preciso escrever testes para tudo desde o primeiro dia?

Não. Comece cobrindo os fluxos mais críticos e mais frequentemente quebrados por mudanças: login, criação de personagem, drop básico, Chaos Machine e entrada em eventos. Expanda a suíte conforme identificar bugs recorrentes que poderiam ter sido pegos por um teste.

Dá para testar sem um cliente de MU completo?

Sim, para a maior parte dos testes de servidor (login, criação de item via GM command, consulta de banco) é possível emular o protocolo diretamente ou usar comandos administrativos, sem abrir o cliente gráfico. Testes de UI/cliente exigem uma abordagem separada (bot com cliente real ou emulador de input).

Com que frequência devo rodar a suíte de regressão?

Idealmente, toda vez que uma configuração, script de evento ou atualização de emulador for alterada em staging, antes de promover para produção. Também é saudável rodar a suíte completa diariamente em staging, mesmo sem mudanças, para pegar regressões causadas por fatores externos (ex.: expiração de dados de teste).

O que fazer quando um teste falha?

Trate como bloqueador: não promova a mudança para produção até entender e corrigir a causa raiz. Documente a falha, a causa e a correção em um changelog interno — isso evita que o mesmo bug reapareça em uma futura atualização sem que ninguém lembre que já foi corrigido antes.

GA
Editor de guias e builds

Gabriel cobre gameplay, builds de classes, PvP e progressão. Testa cada estratégia em servidor antes de publicar.

Continue lendo

Artigos relacionados