☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta integration test. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta integration test. Mostrar todas as mensagens

domingo, 3 de dezembro de 2023

🧪 Um guia para o programador COBOL iniciante entender Unit Test, Component Test, Integration, E2E, APIs, Db2, CICS, IA, Mutation Testing, Chaos Engineering

  

Bellacosa Mainframe e os testes automatizados

☕ Um Café no Bellacosa Mainframe

Dr. Strangelove e a Arte de Parar de se Preocupar e Amar os Testes

🧪 Um guia para o programador COBOL iniciante entender Unit Test, Component Test, Integration, E2E, APIs, Db2, CICS, IA, Mutation Testing, Chaos Engineering e por que um MAXCC=0 não significa que o mundo está salvo

Imagine a cena.

Uma sala subterrânea.

Luzes fracas.

Painéis verdes piscando.

Um enorme mapa operacional ocupa a parede.

Generais discutem nervosamente ao redor de uma mesa enquanto alguém observa um terminal 3270.

De repente, surge a mensagem:

IEF142I PAYROLL STEP030 - STEP WAS EXECUTED - COND CODE 0000

Silêncio.

Um jovem programador COBOL ergue os braços:

— Funcionou!

Do outro lado da mesa, um velho sysprog ajusta os óculos.

— O job terminou com RC=0.

— Exatamente! Funcionou!

— Eu disse que terminou.

— E qual é a diferença?

Nesse momento, uma música imaginária começa a tocar e, em algum lugar entre o JES2, o Db2 e um endpoint REST perdido na nuvem, o Dr. Strangelove levanta lentamente a mão mecânica.

Bem-vindo ao maravilhoso mundo dos testes de software.

Porque existe uma diferença monumental entre:

O PROGRAMA EXECUTOU

e:

O PROGRAMA FEZ A COISA CERTA.

E existe uma diferença ainda maior entre:

O PROGRAMA FEZ A COISA CERTA UMA VEZ.

e:

O SISTEMA CONTINUARÁ FAZENDO A COISA CERTA
QUANDO O BANCO ESTIVER LENTO,
O MQ ESTIVER INDISPONÍVEL,
O USUÁRIO CLICAR DUAS VEZES,
O RACF NEGAR ACESSO
E UM ARQUIVO CHEGAR COM 17 BYTES A MENOS.

Essa diferença se chama engenharia.



🦖 Antes de qualquer coisa: o teste não existe para provar que você é inteligente

Essa talvez seja a primeira lição para quem está começando em COBOL.

Testar não é demonstrar que o programa está bonito.

Não é mostrar ao chefe:

100% DE COVERAGE

e sair correndo em direção ao café.

Testar é produzir evidência de que o comportamento esperado existe.

Pense em um programa COBOL simples:

IF WS-IDADE >= 18
    MOVE 'MAIOR' TO WS-STATUS
ELSE
    MOVE 'MENOR' TO WS-STATUS
END-IF.

Parece fácil.

Então alguém testa:

IDADE = 25
RESULTADO = MAIOR

Passou.

Parabéns.

Temos uma evidência.

Mas ainda sabemos pouco.

Teste também:

IDADE = 17
IDADE = 18
IDADE = 19
IDADE = 0
IDADE = 999
IDADE = -1

Nesse ponto começamos a perceber algo fundamental.

O trabalho interessante não é apenas perguntar:

funciona?

A pergunta interessante é:

em quais condições funciona, em quais condições falha e o que significa falhar corretamente?


🔬 UNIT TEST — o microscópio do programador

Unit Test é o teste da menor unidade lógica razoável.

Em COBOL isso pode ser:

  • um parágrafo;

  • uma SECTION;

  • uma rotina;

  • uma regra de negócio isolada;

  • uma transformação;

  • um cálculo.

Imagine:

CALCULA-JUROS.

    COMPUTE WS-JUROS =
        WS-VALOR * WS-TAXA / 100.

Podemos testar:

VALOR = 1000
TAXA  = 10
JUROS = 100

Mas um bom programador vai além:

VALOR = 0
TAXA = 10

VALOR = 1000
TAXA = 0

VALOR = 1000
TAXA = -10

VALOR = 999999999
TAXA = 99.99

Aqui aparece uma das primeiras curiosidades importantes para quem entra no mundo COBOL:

💰 Dinheiro é uma criatura traiçoeira

COBOL é historicamente excelente para sistemas financeiros justamente porque possui representação decimal adequada.

Mesmo assim, você precisa pensar em:

PIC 9(9)V99
PIC S9(9)V99 COMP-3
ROUNDED
ON SIZE ERROR

Um cálculo pode estar matematicamente correto e ainda produzir problema de tamanho, arredondamento ou sinal.

O Unit Test serve justamente para transformar essas hipóteses em fatos verificáveis.



🧩 COMPONENT TEST — quando várias engrenagens começam a conversar

Um componente é maior que uma função isolada.

Imagine um programa:

PROGRAMA DE CADASTRO

VALIDA CPF
   ↓
VALIDA DATA
   ↓
CALCULA SCORE
   ↓
CLASSIFICA CLIENTE
   ↓
MONTA REGISTRO

Você pode testar cada rotina separadamente.

Depois pode testar o componente completo sem necessariamente acessar Db2, CICS ou MQ.

Por exemplo:

ENTRADA

CPF válido
idade 43
renda 8000

SAÍDA

cliente aceito
score 742
categoria B

Isso começa a testar o comportamento da aplicação como conjunto.

É um pouco como testar o motor inteiro depois de testar pistão, válvula e injeção separadamente.


🟩 INTEGRATION TEST — “Vocês dois realmente conseguem conversar?”

Aqui começam algumas das melhores explosões cinematográficas.

Imagine:

PROGRAMA COBOL
     ↓
Db2

Seu programa pode estar perfeito.

Sua tabela também.

Mas a integração pode falhar porque:

coluna mudou
tipo mudou
package não está bindado
plan errado
authorization falhou
SQLCODE inesperado
connection indisponível

Ou:

COBOL
 ↓
MQ
 ↓
JAVA

O programa COBOL envia:

CUSTOMER-ID=00001234

O Java espera:

customerId=1234

Os dois programas podem passar individualmente em todos os testes.

Juntos:

💥

Esse é o território do Integration Testing.


🐳 Testcontainers e a revolução do “vamos testar com algo parecido com produção”

No mundo distribuído moderno existe uma ferramenta muito interessante chamada Testcontainers.

Ela permite criar dependências reais durante o teste.

Por exemplo:

TESTE
  ↓
sobe PostgreSQL
  ↓
executa aplicação
  ↓
testa
  ↓
derruba PostgreSQL

Isso evita uma velha armadilha:

Produção = banco A
Teste    = banco B parecido

A palavra perigosa aqui é:

parecido.

Em computação, “parecido” é frequentemente irmão de “incidente”.

No mainframe temos uma filosofia semelhante quando criamos ambientes de teste com Db2, VSAM, MQ, CICS e configurações próximas de produção.

Quanto maior a fidelidade do ambiente, maior tende a ser nossa confiança.

Mas também maior o custo.

E aqui começa a aparecer a famosa pirâmide.



🔺 A PIRÂMIDE DOS TESTES

Imagine:

                  /\
                 /  \
                / E2E\
               /------\
              /INTEGR. \
             /----------\
            / COMPONENT  \
           /--------------\
          /      UNIT       \
         /___________________\

A ideia é simples.

Na base:

MUITOS TESTES
RÁPIDOS
BARATOS
ISOLADOS

No topo:

POUCOS TESTES
LENTOS
CAROS
COM MUITAS DEPENDÊNCIAS

Não existe uma porcentagem mágica.

Você encontrará gente repetindo:

70% Unit
20% Integration
10% E2E

Não trate isso como mandamento gravado em pedra por Moisés depois de um IPL.

É apenas uma heurística.

A arquitetura do sistema deve determinar a estratégia.


🎭 END-TO-END — agora queremos saber se o usuário consegue sobreviver

End-to-End Test, ou E2E, acompanha uma jornada completa.

Imagine Internet Banking:

cliente abre navegador
        ↓
login
        ↓
consulta conta
        ↓
faz transferência
        ↓
confirma
        ↓
recebe comprovante

Nos bastidores:

Browser
 ↓
Frontend
 ↓
API Gateway
 ↓
OAuth
 ↓
z/OS Connect
 ↓
CICS
 ↓
COBOL
 ↓
Db2
 ↓
MQ
 ↓
outro sistema

Agora temos algo muito próximo da realidade.

Excelente.

Só existe um pequeno problema:

se o teste falhar, quem matou o coronel?

Pode ser:

browser
CSS selector
rede
token
API
DNS
z/OS Connect
CICS
COBOL
Db2
MQ
serviço remoto
ambiente de teste

Um único:

FAILED

pode significar vinte coisas diferentes.

É por isso que E2E é extremamente valioso, mas também caro.


👻 O monstro chamado Flaky Test

Agora chegamos a uma criatura verdadeiramente perigosa.

O flaky test.

Hoje:

PASS

Amanhã:

FAIL

Executa novamente:

PASS

O programador aprende:

quando falhar, roda novamente

Essa é uma péssima situação.

Depois de alguns meses:

PIPELINE FAILED

e alguém responde:

— Deve ser aquele teste.

Roda novamente.

Passa.

A partir desse momento, o sistema de testes começou a perder autoridade.

Isso é equivalente a um alarme de incêndio que dispara todos os dias sem incêndio.

No começo todo mundo corre.

Depois de três meses:

— Ah, é aquele alarme.

Até o dia em que o prédio realmente pega fogo.


📊 COVERAGE — a estatística favorita para impressionar PowerPoint

Imagine:

IF WS-SALDO >= WS-VALOR
    PERFORM EFETUA-SAQUE
END-IF.

Você cria um teste:

SALDO = 1000
VALOR = 100

A linha foi executada.

Coverage:

100%

Maravilhoso.

Mas você testou:

SALDO = 100
VALOR = 100

?

E:

SALDO = 99
VALOR = 100

?

Coverage mede frequentemente:

o código foi executado?

Não necessariamente:

o comportamento foi corretamente verificado?

É uma diferença monumental.


🧬 MUTATION TESTING — quem testa os testes?

Essa técnica é maravilhosa.

Imagine seu código:

IF WS-IDADE >= 18

Uma ferramenta de mutation testing altera deliberadamente para:

IF WS-IDADE > 18

Depois executa seus testes.

Se eles continuarem passando:

🤨

talvez ninguém esteja realmente testando a fronteira:

IDADE = 18

Mutation Testing basicamente pergunta:

se eu introduzir um pequeno defeito proposital, seus testes percebem?

É uma pergunta muito mais poderosa do que apenas coverage.


🔐 SECURITY TESTING — “funcionar” não significa “ser seguro”

Imagine:

Administrador consegue consultar salários?

Teste:

PASS

Ótimo.

Agora faça a pergunta de segurança:

Usuário comum consegue consultar salários?

Se a resposta for sim:

Parabéns.
Sua aplicação funciona perfeitamente
e está perfeitamente vulnerável.

Security Testing precisa verificar:

autenticação
autorização
privilégio
validação de entrada
segregação
sessão
tokens
exposição de dados

No mainframe:

RACF
SAF
ACEE
profiles
FACILITY
SURROGAT
dataset access
CICS transactions

Um programa COBOL pode produzir exatamente o resultado esperado e ainda ser um desastre de segurança.


⚡ PERFORMANCE TESTING — funciona com um usuário. E com cinquenta mil?

Imagine:

transação demora 50 ms

Excelente.

Então chegam:

10 usuários
100 usuários
1.000 usuários
20.000 usuários

Aí começamos a medir:

CPU
elapsed time
throughput
locks
threads
connections
I/O
queue depth
Db2 contention
CICS MXT
WLM

E essa é uma das grandes vantagens pedagógicas de estudar testes pensando em mainframe.

O mainframe sempre viveu no mundo onde:

funcionalidade e capacidade são problemas diferentes.


🐒 CHAOS ENGINEERING — Dr. Strangelove finalmente assume o comando

Chaos Engineering parece uma ideia de alguém que bebeu café demais:

vamos quebrar deliberadamente coisas para ver o que acontece.

Exemplo:

derrube um serviço

ou:

adicione latência

ou:

bloqueie acesso ao banco

ou:

mate uma instância

e observe.

A pergunta não é:

o sistema funciona?

A pergunta é:

o sistema continua se comportando
de maneira aceitável quando algo falha?

No mundo COBOL podemos traduzir a ideia para:

Db2 indisponível
MQ indisponível
arquivo faltando
arquivo cheio
dataset em uso
VSAM file status diferente de 00
transaction timeout
deadlock
CICS region indisponível

Sistemas empresariais não são construídos apenas para o mundo feliz.

Eles precisam sobreviver ao mundo real.


🦕 TESTANDO BATCH — o capítulo que os diagramas modernos quase sempre esquecem

Agora chegamos à terra natal do COBOL.

Imagine:

JOB001
  ↓
gera arquivo
  ↓
JOB002
  ↓
atualiza Db2
  ↓
JOB003
  ↓
manda MQ
  ↓
JOB004
  ↓
gera relatório

Você precisa testar:

JCL
PROC
COND
IF/THEN/ELSE
GDG
DISP
datasets
SORT
IDCAMS
restart
checkpoint
commit
rerun

Exemplo:

STEP010 RC=0
STEP020 RC=4

O STEP030 deveria rodar?

Depende.

E se:

STEP020 RC=8

?

E se o arquivo estiver vazio?

E se houver registro duplicado?

E se o job cair depois de atualizar metade da tabela?

Você consegue reiniciar?

O processamento é idempotente?

Esse último termo merece atenção.

🔁 Idempotência

Significa, simplificando:

executar novamente não deve causar destruição adicional.

Imagine pagamento:

PAGA R$100

Job cai.

Operador reinicia.

Se o programa pagar novamente:

R$200 enviados

temos um pequeno incidente.

Se repetirmos 300 mil registros...

temos reunião com vice-presidente.


🤖 AGORA A IA ENTRA NA SALA DE GUERRA

Chegamos a GitHub Copilot, ChatGPT, Claude, Cursor, Qodo e outros.

Essas ferramentas conseguem ajudar a:

gerar testes
encontrar edge cases
criar mocks
produzir dados
documentar
explicar erros
analisar cobertura
sugerir cenários

Você pode entregar:

IF WS-SALDO >= WS-SAQUE
   SUBTRACT WS-SAQUE FROM WS-SALDO
END-IF

e perguntar:

Quais casos devo testar?

A IA provavelmente sugerirá:

saldo maior
saldo igual
saldo menor
saque zero
saque negativo
saldo zero
valor máximo

Isso economiza muito tempo.

Mas existe uma pegadinha digna de Stanley Kubrick.


☢️ IA gera o código. IA gera o teste. Tudo passa.

Imagine:

IA interpreta requisito errado
      ↓
gera implementação errada
      ↓
IA usa a mesma interpretação
      ↓
gera teste errado
      ↓
PASS

Temos então uma maravilha tecnológica:

um erro perfeitamente documentado, testado, automatizado e aprovado pelo pipeline.

Essa talvez seja uma das grandes questões da engenharia assistida por IA.

Quanto mais fácil fica gerar código, mais importante fica validar intenção.


🧠 O programador do futuro precisará responder menos “como?” e mais “o quê?”

Antes:

Como escrevo este teste?

Agora uma IA pode escrever boa parte dele.

A pergunta mais importante passa a ser:

O QUE precisa ser testado?

E principalmente:

O QUE ninguém lembrou de testar?

A experiência começa exatamente aí.

Um programador iniciante testa:

usuário fez tudo certo

Um programador experiente pergunta:

usuário clicou duas vezes?

Depois:

a rede caiu no meio?

Depois:

a mensagem chegou duplicada?

Depois:

o token expirou?

Depois:

Db2 deu deadlock?

Depois:

o job reiniciou após commit parcial?

A maturidade em testes não consiste em escrever mais ASSERT.

Consiste em imaginar mais maneiras pelas quais a realidade pode destruir nossas suposições.


🛠️ PASSO A PASSO PARA O COBOLISTA INICIANTE

Vamos transformar tudo em um roteiro prático.

Passo 1 — descubra a regra

Antes de testar:

ENTRADA
PROCESSAMENTO
SAÍDA

Exemplo:

SALDO = 1000
SAQUE = 300
SALDO FINAL = 700

Passo 2 — teste o Happy Path

Comece pelo comportamento esperado.

saldo suficiente
valor válido
cliente válido

Passo 3 — teste fronteiras

Se a regra diz:

IDADE >= 18

teste:

17
18
19

Essa pequena técnica encontra uma quantidade absurda de erros.


Passo 4 — teste entradas ruins

zero
negativo
nulo
branco
máximo
mínimo
duplicado
formato inválido

Passo 5 — teste integrações

Pergunte:

e se Db2 falhar?
e se VSAM retornar file status 23?
e se MQ estiver indisponível?
e se CICS devolver erro?

Passo 6 — teste restart

Principalmente batch.

Pergunte:

se cair no meio,
consigo continuar?

Passo 7 — teste segurança

Pergunte:

quem pode executar?
quem pode ver?
quem pode alterar?

Passo 8 — teste carga

Pergunte:

funciona com uma transação?

Depois:

e com 10 mil?

Passo 9 — observe produção

Esse ponto é frequentemente esquecido.

Produção ensina.

Logs, abends, SMF, RMF, CICS statistics, Db2 traces e incidentes mostram situações que talvez ninguém tenha imaginado em laboratório.

Cada incidente deveria produzir, quando possível:

novo conhecimento
        ↓
novo teste

🎁 EASTER EGGS PARA QUEM CHEGOU ATÉ AQUI

Primeiro:

Dr. Strangelove é uma referência óbvia ao filme de Stanley Kubrick:

Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb.

Nossa versão poderia ser:

How I Learned to Stop Worrying and Love the Test Suite.

Segundo:

Se você encontrar um programador COBOL dizendo:

RC=0, então está certo.

não discuta.

Ofereça café.

Depois pergunte delicadamente:

“Mas você conferiu o arquivo de saída?”

Terceiro:

O verdadeiro teste de integração de qualquer sistema corporativo acontece sexta-feira às 17h43 quando alguém diz:

“É só uma alteração pequena.”

Quarto:

Todo programador algum dia conhece este comando psicológico:

RERUN

Passou na segunda vez?

Ótimo.

Agora você ganhou um problema muito pior.


☕ REGRA BELLACOSA Nº 1

Nunca confunda:

JOB TERMINOU

com:

PROCESSAMENTO CORRETO

Nunca confunda:

TESTE PASSOU

com:

SISTEMA ESTÁ CORRETO

Nunca confunda:

100% COVERAGE

com:

100% CONFIANÇA

E nunca confunda:

IA GEROU 47 TESTES

com:

ALGUÉM ENTENDEU O RISCO.

🧨 A grande conclusão: Testing não é sobre código

No fundo, Testing é engenharia de incerteza.

Estamos tentando responder:

Quanto sabemos sobre o comportamento deste sistema?

Depois:

O que ainda não sabemos?

E finalmente:

Quanto custa descobrir isso somente em produção?

Essa última pergunta muda tudo.

Um bug descoberto durante Unit Test talvez custe minutos.

Durante Integration Test, horas.

Durante homologação, dias.

Depois da implantação, talvez semanas.

Depois de afetar 500 mil clientes...

PowerPoint.

War Room.

Conference Call.

RCA.

Executivos.

Compliance.

Auditoria.

E alguém inevitavelmente perguntará:

Como nossos testes não pegaram isso?

A pergunta quase nunca possui resposta simples.

Porque sistemas reais não são apenas código.

São:

código
+
dados
+
infraestrutura
+
rede
+
configuração
+
segurança
+
operações
+
processos
+
humanos

É por isso que nenhum teste isolado consegue provar que o sistema inteiro é perfeito.

A Pirâmide de Testes, o Testing Trophy, Mutation Testing, Security Testing, Performance Testing e Chaos Engineering são maneiras diferentes de iluminar regiões diferentes da escuridão.

E isso nos leva à talvez mais importante transformação trazida pela inteligência artificial.

Durante décadas, programadores foram valorizados em grande parte por sua capacidade de produzir código.

Agora produzir código está ficando barato.

Muito barato.

Uma IA consegue produzir em segundos aquilo que um desenvolvedor levaria horas para digitar.

Mas produzir confiança continua caro.

Porque alguém precisa entender:

qual é a regra?
qual é o risco?
qual é a exceção?
qual é a fronteira?
qual comportamento seria perigoso?
qual falha é aceitável?
qual falha é catastrófica?

E isso não é simplesmente programação.

Isso é julgamento.

Talvez o programador COBOL de 2030 escreva muito menos código manualmente.

Talvez peça:

“Gere um programa COBOL para esta regra.”

A IA produzirá.

Depois:

“Gere os testes.”

A IA produzirá.

Mas alguém ainda precisará olhar para tudo aquilo e fazer a pergunta que nenhum compilador consegue responder sozinho:

Estamos testando aquilo que realmente importa?

E, quando você chegar a esse ponto, terá deixado de ser apenas alguém que escreve COBOL.

Terá começado a pensar como engenheiro de sistemas.

Em algum lugar distante, o JES2 imprimirá:

MAXCC=0000

Você olhará para a tela.

Não comemorará imediatamente.

Tomará um gole de café.

Abrirá o output.

Conferirá os registros.

Verificará os totais.

Examinará o SQLCODE.

Confirmará os datasets.

E somente então dirá:

— Agora podemos conversar.

Dr. Strangelove sorrirá.

O mainframe continuará funcionando.

E ninguém precisará apertar o botão vermelho.

CHANGE REQUEST CLOSED.

INCIDENT NOT FOUND.

CAFÉ CONSUMIDO COM SUCESSO.

CÂMBIO FINAL.

Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...