Um gerador de endereço aleatório parece uma ferramenta simples até o momento em que você precisa reproduzir uma falha. Se cada execução traz um registro diferente, o defeito que apareceu na terça-feira não aparece na quarta, e a investigação vira arqueologia. Neste texto, explicamos por que aleatoriedade útil é aleatoriedade controlada, mostramos o que significa coerência entre campos quando o registro é sorteado, discutimos reprodução por semente e exportação em lote e fechamos com o desenho de uma bateria de testes que varia o suficiente para encontrar defeito sem virar um gerador de instabilidade.
Aleatório não é o mesmo que arbitrário
Há duas formas de sortear um endereço, e elas produzem resultados muito diferentes. A primeira escolhe cada campo de forma independente: um número qualquer para o imóvel, uma palavra qualquer para a via, um nome qualquer para a cidade e cinco dígitos quaisquer para o código postal. O resultado parece um endereço, passa em qualquer validação que olhe campo por campo e não corresponde a lugar nenhum do país.
A segunda forma sorteia primeiro o país, depois a divisão administrativa, depois a cidade que pertence a essa divisão e só então um código postal compatível com a faixa daquela área. O bairro, quando existe, pertence à cidade escolhida. O telefone carrega o código do país e o prefixo da região. Cada campo continua sendo sorteado, mas dentro de um espaço de valores que faz sentido.
A diferença entre as duas aparece no momento em que o seu sistema tenta validar a combinação. Um formulário que verifica apenas máscara aceita os dois tipos de registro e o teste passa sem provar nada. Um formulário que consulta alguma base de referência, ou que aplica uma regra de coerência entre divisão e código postal, aceita o segundo e recusa o primeiro. Se a sua bateria usa apenas o primeiro tipo, ela está testando o caminho mais fácil do seu próprio código.
Por que a coerência entre campos é o critério real
Coerência é uma propriedade do conjunto, não de cada valor isolado. Um código postal de cinco dígitos é válido em vários países; o que decide se ele serve é a divisão administrativa ao lado dele. O mesmo vale para o código de área do telefone, para o número do documento e para a data de nascimento quando ela é usada para calcular idade.
Em teste, isso tem uma consequência prática pouco intuitiva. Um registro bonito e incoerente é pior do que um registro feio e coerente, porque o primeiro esconde o defeito. Se todos os seus exemplos têm cidade e código postal que combinam por acaso, os caminhos de erro do seu código nunca são executados, e a cobertura que aparece no relatório não corresponde a nada real.
Por isso, um gerador que se preocupa com o dado de teste separa duas funções. Ele produz exemplos coerentes para os casos em que o sistema deve aceitar, e você mantém à parte uma pequena coleção de exemplos deliberadamente incoerentes para os casos em que o sistema deve recusar ou avisar. As duas coleções juntas descrevem o comportamento esperado; uma sozinha descreve apenas metade dele.
O que significa reproduzir o mesmo registro?
Reprodução é a capacidade de obter de novo exatamente o mesmo registro a partir da mesma entrada. Em um gerador com semente, a entrada é um identificador curto: o mesmo identificador e o mesmo país devolvem sempre o mesmo endereço, hoje e no mês que vem, na sua máquina e na do colega.
A utilidade disso é grande e não é óbvia no começo. Um relatório de defeito pode citar o identificador usado e quem for investigar consegue o mesmo dado sem anexar arquivo. Um teste automatizado que compara a saída com um valor esperado precisa de estabilidade, porque um teste de igualdade alimentado por sorteio puro falha de vez em quando e ninguém entende por quê. E um ambiente de demonstração pode ser reconstruído do zero, com os mesmos endereços, sem depender de backup.
Vale distinguir dois modos e marcar no próprio caso de teste qual deles ele espera. O modo reproduzível serve para verificação, quando a resposta correta é conhecida. O modo variável serve para exploração, quando a pergunta é se o sistema aceita qualquer entrada plausível. Misturar os dois é a origem mais comum de testes instáveis, e o sintoma quase sempre aparece como falha intermitente atribuída a infraestrutura.
Como usar a exportação em lote nos testes
Quando a bateria precisa de muitos registros, digitar um por vez não escala. A exportação em formato de texto separado por vírgulas resolve o problema de forma direta: você gera um conjunto, guarda o arquivo no repositório e o teste lê o arquivo em vez de chamar o gerador a cada execução.
Essa abordagem tem duas vantagens. A primeira é determinismo, porque o arquivo é imutável e a bateria produz sempre o mesmo resultado. A segunda é revisabilidade: um conjunto de endereços em arquivo pode ser lido e discutido em uma revisão de código, e dá para perceber se ele cobre poucos países ou se todos os exemplos vêm da mesma região.
Há um cuidado que costuma ser esquecido: o arquivo precisa de cabeçalho estável e de campos com aspas quando contêm vírgula, ponto e vírgula ou quebra de linha. Endereços têm vírgulas com frequência, e um exportador ingênuo produz um arquivo que parece correto e desalinha as colunas na terceira linha. Um teste que lê esse arquivo falha de forma confusa, e a causa real está no formato e não na lógica.
Se o objetivo é popular um banco de homologação com muitos registros, o mesmo arquivo serve como ponto de partida, mas vale gerar em blocos e verificar de tempos em tempos se as combinações entre divisão e código postal continuam válidas. No gerador de endereços essa relação é mantida na origem, e o resultado sai pronto para uso em lote.
Quais são os erros mais comuns em dados multinacionais?
O primeiro e mais frequente é o par entre divisão e código postal. Quem gera cada campo de forma independente produz um endereço de país A com código de país B, ou uma cidade que não pertence àquele estado, e o problema só aparece quando alguém tenta usar o registro.
O segundo é o telefone. Código de área pertence a uma região, e um número com prefixo de uma cidade colado a um endereço de outra é uma incoerência que passa em todo teste de formato. O terceiro é o nome da pessoa: listas de nomes são específicas de cada cultura, e um nome que não existe naquele país não é um defeito grave por si só, mas reduz o valor do teste quando o objetivo é verificar a exibição de caracteres não latinos.
O quarto é o formato de data. Países escrevem datas em ordens diferentes, e um gerador que emite sempre o mesmo formato obriga o seu sistema a converter, o que pode esconder defeitos de interpretação. O quinto é o código do país: para uma boa parte dos sistemas o campo relevante é a sigla de duas letras, e emitir o nome por extenso em um campo que espera sigla produz recusa.
Para quem precisa manter esse conjunto em vários países ao mesmo tempo, o resumo sobre escalar dados de teste entre países trata da organização por região, e o texto sobre formatos de endereço por país mostra onde as regras de validação costumam divergir.
Onde o endereço aleatório ajuda em carga e fuzzing
Em teste de carga, o objetivo é medir o sistema e não a qualidade do dado, mas a qualidade do dado interfere no resultado. Se todos os registros têm o mesmo tamanho, o tempo médio de resposta medido é o de um caso fácil. Se todos são do mesmo país, a consulta de normalização sempre pega o mesmo caminho. Variar países, comprimentos e presença de acentuação produz um número mais próximo do que acontece em produção.
Em teste de fuzzing de formulário, a aleatoriedade é usada para encontrar combinações que o autor do código não previu. Vale incluir nomes de via muito longos, palavras sem espaço, acentuação, caracteres de outros alfabetos, códigos postais começando por zero e campos opcionais ora preenchidos, ora vazios. O objetivo não é gerar lixo, e sim variar dentro do plausível para que o sistema revele os próprios limites.
Uma prática que reduz bastante o ruído é separar o conjunto de entradas do conjunto de verificações esperadas. Assim, quando um caso falha, dá para saber se o defeito está no sistema ou no dado de entrada.
Limites de uso e responsabilidade
Os endereços produzidos são dados sintéticos. O formato é o do país escolhido e os campos são coerentes entre si, mas nenhum registro corresponde a um imóvel real, a uma pessoa real ou a uma conta real. Eles não devem ser usados para entregas, para cadastro em serviços, para simular verificação de identidade ou para qualquer finalidade que dependa de um endereço verdadeiro.
O uso adequado é testar software: homologar formulários, popular ambientes, verificar normalização e validação, medir carga com dado variado. Se o seu trabalho é desenhar um formulário que aceite vários países, comece pelo panorama de formatos de endereço por país e só depois fixe as regras no código, porque uma regra escrita cedo demais custa mais para desfazer do que para escrever.