Testes & QA

Massa de Dados CNAB para Testes em Staging

Como gerar e mockar arquivos CNAB de remessa e retorno sintéticos para testes automatizados e integração contínua sem depender do banco.

22 de julho de 20266 min de leituraDevThru

Um dos maiores gargalos no desenvolvimento de software financeiro no Brasil é a dependência de homologação bancária. Em ambientes de **Staging, QA e CI/CD**, nem sempre os desenvolvedores possuem acesso aos portais de sandbox dos bancos para gerar arquivos reais de retorno (.ret) ou validar arquivos de remessa (.rem).

Para manter uma esteira de entregas ágil e automatizada, a melhor abordagem é criar **geradores de massa de dados CNAB sintéticos**. Neste artigo, vamos aprender como estruturar mocks de arquivos CNAB 240 e CNAB 400 para cenários de liquidação, rejeição e alteração de títulos.

Por que Mockar Arquivos CNAB em Testes?

  1. Independência de Terceiros: Testes automatizados unitários e de integração (E2E) não devem falhar por indisponibilidade de APIs ou portais bancários externos.
  2. Simulação de Erros de Borda (Edge Cases): É difícil forçar um banco real em homologação a emitir um código de rejeição específico (ex: "CPF do Sacado Inválido" ou "Agência/Conta Destino Inexistente"). Com mocks sintéticos, você pode simular qualquer ocorrência instantaneamente.
  3. Conformidade com a LGPD: Arquivos de remessa reais contêm dados sensíveis de clientes (CPF, Nome, Endereço, Valores). Utilizar arquivos de produção em ambientes de desenvolvimento viola a LGPD. Deve-se utilizar sempre Dados Fictícios de Pessoas.

Estrutura de um Gerador de Mock CNAB 400 em JavaScript

Abaixo está uma função utilitária em TypeScript/Node.js para construir uma string de arquivo de retorno CNAB 400 mockado com ocorrência de liquidação (pagamento com sucesso):

interface MockTituloRetorno {
  nossoNumero: string;
  valorPagoCents: number;
  dataPagamentoDDMMAA: string; // ex: '220726'
  codigoOcorrencia?: string; // '06' = Liquidação normal
}

export function gerarMockCnab400Retorno(
  codigoBanco: string, // ex: '341' (Itaú)
  razaoSocialEmpresa: string,
  cnpjEmpresa: string,
  titulos: MockTituloRetorno[]
): string {
  const padRight = (str: string, len: number, char = ' ') =>
    str.padEnd(len, char).slice(0, len);
  const padLeft = (str: string, len: number, char = '0') =>
    str.padStart(len, char).slice(0, len);

  const linhas: string[] = [];

  // 1. Header do Arquivo (400 caracteres)
  let header = '0'; // Tipo Registro Header
  header += '2'; // 2 = Retorno
  header += 'RETORNO'; // Literal
  header += '01'; // Código de Serviço: Cobrança
  header += padRight('COBRANCA', 15);
  header += padLeft(cnpjEmpresa.replace(/D/g, ''), 14);
  header += padRight(razaoSocialEmpresa, 30);
  header += padLeft(codigoBanco, 3);
  header += padRight('BANCO DE TESTE', 15);
  header += '220726'; // Data da gravação (DDMMAA)
  header += padRight('', 287); // Complemento do registro até 400
  header += padLeft('000001', 6); // Número Sequencial
  linhas.push(header);

  // 2. Linhas de Detalhe (400 caracteres cada)
  titulos.forEach((t, index) => {
    const seq = padLeft((index + 2).toString(), 6);
    const ocorrencia = t.codigoOcorrencia || '06'; // 06 = Pago / Liquidado

    let detalhe = '1'; // Tipo Registro Detalhe
    detalhe += padLeft(cnpjEmpresa.slice(0, 14), 14);
    detalhe += padLeft(t.nossoNumero, 8);
    detalhe += padRight('', 40);
    detalhe += '1'; // Carteira
    detalhe += padLeft(ocorrencia, 2); // Código da Ocorrência
    detalhe += t.dataPagamentoDDMMAA; // Data Ocorrência no Banco
    detalhe += padRight(t.nossoNumero, 8);
    detalhe += padRight('', 175);
    detalhe += padLeft(t.valorPagoCents.toString(), 13); // Valor pago em centavos
    detalhe += padRight('', 120);
    detalhe += seq; // Sequencial da linha

    linhas.push(detalhe);
  });

  // 3. Trailer do Arquivo (400 caracteres)
  const totalLinhas = linhas.length + 1;
  let trailer = '9'; // Tipo Registro Trailer
  trailer += '2'; // Retorno
  trailer += '01'; // Cobrança
  trailer += padLeft(codigoBanco, 3);
  trailer += padRight('', 379);
  trailer += padLeft(totalLinhas.toString(), 6);
  linhas.push(trailer);

  return linhas.join('
');
}

Cenários Essenciais de QA para Cobrança Bancária

Ao construir seus testes automatizados em frameworks como Jest, Vitest ou Cypress, certifique-se de testar pelo menos estes 4 cenários principais:

Cenário de Teste Ocorrência CNAB Resultado Esperado no Sistema
Liquidação Normal 06 (CNAB 400) / 06 (CNAB 240) Marcar fatura/pedido como Pago e liberar serviço.
Título Rejeitado 03 (Entrada Rejeitada) Notificar a equipe financeira e exibir o motivo da rejeição do banco.
Baixa Manual ou Expirada 09 ou 10 (Baixado no Banco) Marcar título como Cancelado/Expirado.
Entrada Confirmada 02 (Entrada Confirmada) Confirmar que o boleto foi registrado com sucesso na CIP/Banco.

Inspecionando os Mocks de Teste

Após gerar seus arquivos sintéticos em seu script de testes, utilize o Leitor de CNAB do DevThru para verificar se todos os campos posicionais e tamanhos de linha estão 100% corretos antes de rodar a suíte de testes E2E!

🛠️ Experimente na prática

Use nossas ferramentas online gratuitas — sem cadastro, direto no navegador.

CNABQAtestesmockstagingfintechCI/CD

Esse artigo foi útil para você?