A Arte De Iluminar O Passado: Selenium E A Arqueologia De Bugs Em Sistemas Legados

A Arte De Iluminar O Passado - Selenium e Testes Automatizados

PRÓLOGO: O CHAMADO DO LEGADO

Era uma manhã comum de dezembro quando recebi o chamado. Do outro lado da linha, a voz preocupada do gerente de TI: "Temos um problema. O sistema de gestão que roda há mais de uma década começou a apresentar falhas críticas. Os usuários não conseguem salvar, editar ou excluir registros em módulos essenciais. Pior ainda: não temos documentação atualizada dos testes."

O sistema em questão era uma aplicação JavaEE monolítica, construída em uma época onde frameworks como Spring Boot ainda não dominavam o mercado. WildFly (anteriormente JBoss), JPA, Hibernate, Stored Procedures SQL Server, AngularJS 1.x no frontend - uma verdadeira cápsula do tempo tecnológica, mas que ainda processava operações críticas de negócio todos os dias.

Como muitos sistemas legados em grandes organizações, ele sofria do "paradoxo da essencialidade": era vital demais para ser substituído rapidamente, mas antigo demais para ter uma equipe completa dedicada à sua manutenção. E agora, bugs silenciosos começavam a emergir das profundezas do código.

Este é o relato de como transformamos o Selenium, uma ferramenta de automação web, em uma máquina do tempo visual - capaz não apenas de encontrar bugs, mas de contar suas histórias através de vídeos que documentam cada falha e cada vitória na jornada de correção.


CAPÍTULO 1: O SILÊNCIO DOS BUGS

O primeiro desafio foi entender a natureza dos problemas. Os usuários relatavam que ao tentar salvar uma nova empresa no módulo de administração, o sistema simplesmente não respondia. Nenhuma mensagem de erro. Nenhum feedback. Apenas silêncio.

Em sistemas modernos, com logs estruturados e ferramentas de APM (Application Performance Monitoring), rastrear isso seria questão de minutos. Mas em sistemas legados, especialmente aqueles que evoluíram através de múltiplas equipes ao longo de anos, a história é diferente.

O código tinha camadas sobre camadas:

  • Frontend AngularJS 1.x com lógica de negócio misturada aos controllers
  • APIs REST construídas com JAX-RS, mas sem seguir completamente RESTful
  • Camada de negócio usando JPA e Hibernate, mas também JDBC direto
  • Stored Procedures SQL Server que misturavam lógica de dados e regras de negócio
  • Configurações XML espalhadas por diferentes arquivos
  • Dependências que não eram atualizadas há anos por medo de quebrar algo

Como você testa algo assim? Como você documenta bugs de forma que qualquer pessoa - desenvolvedor, analista de negócio, ou até mesmo o usuário final - possa entender exatamente o que está errado?

A resposta veio em três palavras: automação, visualização e narrativa.


CAPÍTULO 2: SELENIUM COMO TESTEMUNHA OCULAR

Selenium WebDriver não é apenas uma ferramenta para automatizar testes. Quando usado criativamente, torna-se uma testemunha ocular digital - capaz de observar, documentar e reportar exatamente o que acontece na interface do usuário, frame por frame.

Minha estratégia foi construir um framework de testes que não apenas verificasse se algo funciona ou não, mas que MOSTRASSE o que acontecia. Para isso, desenvolvi um sistema baseado em Python com os seguintes pilares:

1. GRAVAÇÃO DE VÍDEO CONTÍNUA

Cada teste Selenium inicia gravando a tela usando OpenCV e pyautogui. Não capturas de tela estáticas - vídeos completos em 1920x1080 a 30 FPS. Isso permite ver não apenas o estado final, mas toda a jornada: cada clique, cada campo preenchido, cada espera de carregamento.

Gravação de Testes Automatizados em Vídeo MP4

2. TIMESTAMPS E CONTEXTO

Cada ação importante é marcada no tempo. Quando o teste preenche um campo, o timestamp é registrado. Quando clica em salvar, outro timestamp. Quando verifica se o registro aparece na listagem, mais um timestamp. Isso permite correlacionar o vídeo com os logs de teste e até com logs do servidor.

3. MODO DUAL: ANTES E DEPOIS

Aqui está a mágica: cada bug tem DOIS vídeos. O primeiro, gravado antes da correção, mostra o comportamento incorreto em toda sua glória - ou horror. O segundo, gravado após a correção, demonstra que o problema foi resolvido. É a prova definitiva, visual e irrefutável.

4. ESTRUTURA DE CARDS

Para cada bug, criamos um "card" - um documento de texto estruturado que contém: título, descrição, passos para reprodução, resultado esperado vs atual, evidências (links para os vídeos), e um campo para a tag de commit da correção. É como um JIRA card, mas completamente rastreável e versionado junto com o código de teste.


CAPÍTULO 3: A ANATOMIA DE UM BUG LEGADO

Vou contar a história de um bug específico - vamos chamá-lo de BUG-003.

O SINTOMA

O módulo "Manter Empresa" permitia visualizar empresas cadastradas, mas não permitia criar, editar ou excluir nenhuma. Era como ter uma biblioteca onde você pode ver os livros, mas não pode tocá-los.

A INVESTIGAÇÃO

O teste Selenium revelou algo interessante. Quando você preenchia o formulário e clicava em "Salvar", o navegador enviava uma requisição HTTP POST para a API. A requisição retornava HTTP 200 OK. Mas quando voltava para a listagem, o registro não estava lá.

Isso significava que o problema não estava no frontend. A requisição estava sendo feita corretamente. O backend estava respondendo sem erro. Mas os dados não estavam sendo persistidos.

O MERGULHO NO CÓDIGO

Aqui começou a arqueologia de código. O caminho do dado era:

  1. AngularJS Controller → enviava objeto JSON com os dados
  2. JAX-RS Resource → recebia e chamava o serviço
  3. Serviço de Negócio → aplicava regras e chamava o DAO
  4. DAO JPA → usava EntityManager para chamar Stored Procedure
  5. Stored Procedure → SQL Server, lógica de CRUD

Em qual camada estava o problema? O vídeo do Selenium mostrava que a UI funcionava. Os logs mostravam que a requisição chegava ao backend. O banco tinha os dados antigos, mas não os novos.

A REVELAÇÃO

Após horas de debugging, descobri: a Stored Procedure retornava um ResultSet com os dados, seguido de parâmetros de saída. O Hibernate/JPA estava tentando mapear esse ResultSet para a entidade JPA, mas como era resultado de uma SP (não de uma query nativa simples), entrava em conflito com o gerenciamento de contexto de persistência.

O resultado? A operação executava, mas o Hibernate não commitava a transação corretamente. Os dados ficavam em um limbo - nem salvos, nem rejeitados.

A SOLUÇÃO CRIATIVA

A correção exigiu criatividade: abandonar o JPA para essa operação específica e usar JDBC puro através do Session.doWork() do Hibernate. Isso deu controle total sobre o CallableStatement, permitindo processar primeiro o ResultSet, depois os parâmetros de saída, exatamente na ordem que a SP esperava.

Mas havia outro problema: o frontend enviava apenas o ID ao deletar, mas o backend esperava o objeto completo devido a como o Jackson desserializava JSON. A solução: aceitar Map<String,Object> no endpoint de exclusão.

A PROVA VISUAL

O vídeo "ANTES" do Selenium mostrava: formulário preenchido, botão clicado, volta para listagem, registro não aparece. Frustração visual pura.

O vídeo "DEPOIS" mostrava: formulário preenchido, botão clicado, volta para listagem, registro ESTÁ LÁ. O gosto da vitória em 30 segundos de MP4.


CAPÍTULO 4: A ESTRUTURA QUE SUSTENTA A MAESTRIA

Construir testes automatizados para sistemas legados é como fazer arqueologia: você precisa de ferramentas especializadas e muita paciência. Aqui está a estrutura que desenvolvi:

ORGANIZAÇÃO PROFISSIONAL

testes/
├── 01_plano-teste/              # Estratégia e planejamento
│   ├── PLANO_MESTRE_TESTES.md
│   └── ESTRATEGIA_AUTOMACAO.md
├── 02_ambientes/                # Configs de dev, qa, prod
│   └── config.env.template
├── 03_casos-teste/              # Testes organizados por tipo
│   ├── funcional/
│   │   └── bug/
│   │       ├── test_bug001_*.py
│   │       ├── test_bug002_*.py
│   │       └── test_bug003_*.py
│   ├── integracao/
│   └── regressao/
├── 04_evidencias/               # Vídeos e screenshots
│   ├── videos/
│   │   ├── BUG-003_ANTES.mp4
│   │   └── BUG-003_DEPOIS.mp4
│   └── screenshots/
├── 05_relatorios/               # Cards de bugs e relatórios
│   └── bugs/
│       └── CARD_BUG-003.txt
├── 06_dados-teste/              # Massa de dados
└── 07_ferramentas/              # Utilitários
    ├── src/
    │   ├── utils/
    │   │   ├── video_recorder.py
    │   │   └── selenium_base.py
    │   └── config/
    └── templates/

PADRÕES DE CÓDIGO

Cada teste segue uma estrutura narrativa:

class TestBug003Empresa:
    """
    BUG-003: Manter Empresa - CRUD não funciona
    Evidências: videos/BUG-003_*.mp4
    """
    
    def setup_method(self):
        """Prepara ambiente: inicia gravação de vídeo"""
        self.recorder = VideoRecorder("BUG-003")
        self.driver = self.init_selenium()
        
    def test_001_criar_empresa_deve_persistir(self):
        """
        CENÁRIO: Criar nova empresa
        DADO que estou na tela de Manter Empresa
        QUANDO preencho os dados e salvo
        ENTÃO o registro deve aparecer na listagem
        """
        # Código do teste
        
    def teardown_method(self):
        """Finaliza: salva vídeo com timestamp"""
        self.recorder.stop()
        self.driver.quit()

GRAVAÇÃO INTELIGENTE

O VideoRecorder não apenas grava - ele contextualiza:

  • Nome do arquivo: 2026_01_15_08_18_38_BUG-003_Empresa_CRUD.mp4
  • Resolução: 1920x1080 (full HD, legível em qualquer tela)
  • FPS: 30 (fluido, não robotizado)
  • Codec: H.264 (compatível com qualquer player)
  • Metadata: timestamp de início, nome do teste, resultado

CAPÍTULO 5: OS DESAFIOS DA JORNADA

Nem tudo foram flores. Testar sistemas legados com Selenium traz desafios únicos:

1. ESPERAS IMPREVISÍVEIS

AngularJS 1.x não tem indicadores confiáveis de quando terminou de carregar. Às vezes, a página parece pronta, mas ainda está executando $digest cycles. Solução: esperas explícitas combinadas com verificações de estado do Angular.

2. MODAIS E POPUPS ANTIGOS

A aplicação usava modais jQuery UI, não componentes modernos. O Selenium precisa de estratégias diferentes para interagir com eles - às vezes, executando JavaScript diretamente no navegador.

3. TIMEZONES E FORMATOS DE DATA

O sistema foi construído para um fuso horário específico, mas os testes rodavam em ambientes diferentes. Datas apareciam formatadas de formas inesperadas. Solução: normalização de datas no código de teste.

4. STORED PROCEDURES STATEFUL

Algumas SPs mantinham estado entre execuções (variáveis globais, tabelas temporárias). Isso causava interferência entre testes. Solução: limpeza explícita do banco antes de cada teste.

5. GRAVAÇÃO DE VÍDEO CONSOME RECURSOS

Gravar 1920x1080 a 30 FPS consome CPU e disco. Em máquinas mais lentas, isso interferia com os testes. Solução: opção de desabilitar vídeo em testes de desenvolvimento, mantendo apenas em testes oficiais.

6. PRIVACIDADE E DADOS SENSÍVEIS

O sistema lidava com dados corporativos. Os vídeos não podiam vazar informações reais. Solução: uso exclusivo de dados de teste sintéticos, claramente identificáveis (como "EMPRESA TESTE 623").


CAPÍTULO 6: O PODER DA NARRATIVA VISUAL

O que descobri ao longo dessa jornada é que bugs não são apenas problemas técnicos - são histórias. E histórias precisam ser contadas de forma que as pessoas se importem.

ANTES DE VÍDEOS

  • "O módulo X não salva dados" → Resposta: "Funciona na minha máquina"
  • Discussões intermináveis sobre se o bug existe
  • Semanas para reproduzir em ambiente controlado
  • Comunicação por email com capturas de tela confusas

DEPOIS DE VÍDEOS

  • "Assista este vídeo de 30 segundos" → Resposta: "Entendi, vou corrigir"
  • Zero ambiguidade sobre a existência do bug
  • Reprodução imediata através do código de teste automatizado
  • Evidência visual que qualquer stakeholder entende

Os vídeos transformaram conversas:

Email típico ANTES:

Assunto: Bug em Empresa

Oi, quando tento salvar não funciona. Cliquei no botão mas não salvou.
Pode ver?

Email típico DEPOIS:

Assunto: BUG-003 - Evidência Visual

Olá,

Identificamos falha crítica no módulo Manter Empresa.

Evidências:
- Vídeo do problema: BUG-003_ANTES.mp4
- Card completo: CARD_BUG-003_EMPRESA.txt
- Teste reproduzível: test_bug003_empresa.py

Assista o vídeo (30s) para visualizar o comportamento incorreto.

Causa raiz já identificada: conflito JPA/Hibernate com ResultSet de SP.
Proposta de correção em andamento.

A diferença? Profissionalismo, clareza e respeito pelo tempo de todos.


CAPÍTULO 7: A ARTE DA COMPARAÇÃO

O momento mais satisfatório é criar o vídeo "DEPOIS". É a prova de que o esforço valeu a pena.

Nosso processo:

1. CAPTURA DO "ANTES"

  • Executa teste automatizado
  • Bug se manifesta exatamente como reportado
  • Vídeo gravado e salvo com sufixo "_ANTES"
  • Timestamp registrado no card do bug

2. ANÁLISE E CORREÇÃO

  • Investigação da causa raiz
  • Implementação da solução
  • Code review e testes manuais
  • Commit com mensagem padronizada

3. CAPTURA DO "DEPOIS"

  • Executa MESMO teste automatizado
  • Bug não se manifesta mais
  • Vídeo gravado e salvo com sufixo "_DEPOIS"
  • Timestamp registrado no card

4. COMPARAÇÃO LADO A LADO

  • Editamos os dois vídeos em um split-screen
  • Esquerda: ANTES (vermelho)
  • Direita: DEPOIS (verde)
  • Narração opcional explicando a correção

Essa comparação visual é poderosa em apresentações para stakeholders. É tangível, compreensível e impressionante.


CAPÍTULO 8: LIÇÕES APRENDIDAS

Após meses trabalhando com Selenium em sistemas legados, aqui estão as lições que levarei para sempre:

1. AUTOMAÇÃO NÃO É APENAS SOBRE VELOCIDADE

É sobre consistência, documentação e comunicação. Um teste manual pode ser mais rápido hoje, mas um teste automatizado com vídeo vale ouro amanhã.

2. SISTEMAS LEGADOS MERECEM RESPEITO

É fácil criticar código antigo. Mas ele sobreviveu anos, processou milhões de transações e suportou negócios inteiros. Nossa missão é honrá-lo enquanto o modernizamos.

3. VISUALIZAÇÃO É COMUNICAÇÃO

Um vídeo de 30 segundos comunica mais que 30 páginas de documentação. Invista tempo em tornar suas evidências visuais e acessíveis.

4. PADRÕES SALVAM VIDAS

Estrutura de pastas, nomenclatura de arquivos, formato de cards - tudo isso parece burocracia até você ter 50 bugs para gerenciar. Então, vira salvação.

5. TESTES SÃO DOCUMENTAÇÃO EXECUTÁVEL

O código do teste É a documentação do comportamento esperado. Se alguém quer entender como o sistema deve funcionar, mostre o teste.

6. CRIATIVIDADE > FERRAMENTAS

Selenium é apenas uma ferramenta. O que faz a diferença é COMO você a usa. Pense fora da caixa: grave vídeos, crie narrativas, construa cards de bug.

7. PRIVACIDADE É NÃO-NEGOCIÁVEL

Nunca, jamais, use dados reais em testes ou vídeos de evidência. Sempre dados sintéticos, sempre mascarados, sempre seguro.


CAPÍTULO 9: O FUTURO QUE CONSTRUÍMOS

O sistema legado ainda está lá, rodando, processando operações críticas. Mas agora, ele tem algo que não tinha antes: uma rede de segurança.

Cada módulo crítico tem:

  • Testes automatizados que reproduzem cenários reais
  • Vídeos que documentam o comportamento esperado
  • Cards que explicam cada bug já corrigido
  • Um histórico vivo de evolução

Quando um novo desenvolvedor entra na equipe, ele não recebe apenas código. Ele recebe histórias. Ele assiste aos vídeos. Ele entende o PORQUÊ de cada decisão técnica, porque pode ver o problema que ela resolveu.

Quando um stakeholder pergunta "por que isso demora tanto?", mostramos os vídeos dos bugs que já corrigimos. Mostramos a complexidade. E eles entendem.

O Selenium deixou de ser apenas uma ferramenta de teste. Tornou-se nosso contador de histórias digital, nossa memória coletiva, nossa prova de que importamos com qualidade.


EPÍLOGO: A MAESTRIA ESTÁ NO DETALHE

Meses depois daquele primeiro chamado, o sistema está mais estável. Não porque reescrevemos tudo - mas porque entendemos tudo. Porque documentamos tudo. Porque testamos tudo.

A verdadeira maestria em trabalhar com Selenium e sistemas legados não está em conhecer todas as APIs do WebDriver. Está em:

  • Saber quando gravar e quando apenas validar
  • Entender como contar a história de um bug através de um vídeo
  • Ter empatia com quem vai assistir seus testes rodando
  • Respeitar a privacidade e a segurança
  • Construir não apenas testes, mas documentação viva
  • Transformar bugs em oportunidades de aprendizado

Cada vídeo "_ANTES.mp4" é um memorial de um problema.
Cada vídeo "_DEPOIS.mp4" é um certificado de conquista.
E cada card de bug é um capítulo na história de um sistema que se recusa a morrer - porque ainda tem valor, ainda serve pessoas, ainda importa.

No final, não estamos apenas testando software.
Estamos preservando legados.
Estamos iluminando o passado para construir um futuro melhor.
Estamos praticando a arte de cuidar do que veio antes de nós.

E isso, sim, é maestria.


SOBRE ESTE ARTIGO

Este artigo é baseado em experiências reais de testes automatizados em sistemas legados JavaEE, mas todos os nomes de empresas, aplicações e dados foram alterados ou omitidos para preservar a privacidade e a confidencialidade.

As técnicas descritas são aplicáveis a qualquer sistema legado que precise de modernização com segurança e qualidade.

O código e as estruturas mencionadas estão disponíveis como referência para equipes que enfrentam desafios similares.