Генератор случайных адресов выдаёт записи, которые выглядят как настоящие адреса конкретной страны: улица, город, административная единица, индекс и телефон, собранные по правилам этой страны. Случайность здесь нужна не ради разнообразия самого по себе, а чтобы заполнить форму или базу множеством разных значений, не придумывая их вручную. Ошибка новичка — понимать случайность как произвольность и складывать адрес из независимо выбранных частей: тогда получается строка, где город лежит в чужом регионе, а индекс не подходит ни к тому, ни к другому. Дальше разберём, почему случайный адрес обязан быть согласованным, зачем нужна воспроизводимость и какие дефекты чаще всего появляются при генерации сразу для многих стран. В конце вы сможете собрать набор, который не рассыпается при первом же прогоне автотестов.
Чем случайный адрес отличается от произвольного
Произвольный адрес собирается из независимых значений: случайное слово на месте улицы, случайное число на месте индекса, случайный город из общего списка. Такой набор выглядит разнообразным, но почти каждая запись в нём внутренне противоречива. Проверка формата её пропустит, а любая осмысленная проверка связей — нет, и вы будете отлаживать дефекты, которых в реальной работе не бывает.
Случайный адрес в правильном смысле выбирается из набора допустимых записей. Страна определяет справочник, город берётся из этой страны, индекс — из этого города, телефонный код — из той же местности. Формат полей тоже берётся из страны: где-то индекс состоит только из цифр, где-то содержит буквы, а где-то его нет вовсе. Только после этого значения можно считать случайными, потому что случайным остаётся выбор, а не структура.
Третье отличие касается набора символов. Названия улиц и населённых пунктов принадлежат конкретному языку, и запись, где к латинской структуре адреса приклеено название в другой графике, сразу выдаёт себя. Для формы это не косметическая мелочь: именно на таких записях проверяются шрифты, сортировка и правила нормализации.
Почему воспроизводимость важнее разнообразия
Если генератор выдаёт новую запись при каждом обновлении страницы, работать с ним в автотестах почти невозможно. Тест, который упал, невозможно повторить: при следующем запуске данные уже другие, и понять, был ли дефект в логике или в конкретном значении, нельзя. Отчёт об ошибке теряет смысл, потому что в нём описана запись, которой больше не существует.
Полезное свойство генератора — детерминированность при заданном входе. Один и тот же ключ, одна и та же страна и один и тот же набор параметров всегда дают в точности ту же запись. Это позволяет закрепить эталон в тесте и сравнить результат, а не только факт отсутствия ошибки.
Из этого следует, что в проекте должны существовать два режима, и смешивать их нельзя. Первый — эталонный, где запись зафиксирована и сравнение идёт с известным результатом. Второй — исследовательский, где при каждом запуске берётся новая запись, чтобы наткнуться на дефекты, которых фиксированный образец не показывает. Если тест ждёт стабильную запись, а получает новую, он падает через раз; если он ждёт новую, а получает старую, он перестаёт находить что-либо. Как разложить это по разным наборам, подробно описано в статье про адресные данные в тестовых наборах.
Что даёт один и тот же ключ при повторной генерации?
Ключ превращает случайность в адресуемую запись. Пока он не изменён, запись остаётся той же, и её можно обсуждать с коллегами, вставлять в отчёт и хранить в репозитории как образец. Это удобнее, чем описывать адрес словами: вместо пересказа достаточно назвать ключ и страну, и любой участник команды получит ровно те же данные.
Второе применение ключа — воспроизведение инцидента. Когда пользователь сообщает о проблеме и вы можете повторить его данные, отладка идёт по существу, а не по догадкам. Третий случай — сравнение версий: зафиксировав ключ, можно прогнать один и тот же набор через старую и новую сборку и увидеть разницу в поведении, а не в данных.
Практическое правило простое: меняйте ключ сознательно, когда действительно нужен другой набор, и никогда не меняйте его случайно. Если генерация значения зависит от текущего времени или от порядка запросов, ключ перестаёт работать как якорь, и вся конструкция рассыпается.
Какие ошибки появляются при генерации сразу многих стран?
Первая и самая частая — перенос справочника одной страны на другую. Список административных единиц, взятый не оттуда, даёт адрес, который форма примет, а логика доставки отвергнет. Это особенно заметно, когда у двух стран похожая структура и одинаковые названия уровней.
Вторая ошибка — неверная форма индекса. В одних странах он состоит только из цифр и имеет фиксированную длину, в других содержит буквы, в третьих отсутствует как обязательное поле. Форма, которая проверяет индекс универсальным шаблоном, будет либо отвергать корректные записи, либо принимать мусор. Об этих различиях подробно говорится в статье про форматы почтовых индексов.
Третья ошибка — несовпадение телефонного кода и населённого пункта. Код зоны привязан к местности не во всех странах одинаково, и универсальная проверка здесь вредна не меньше, чем полное её отсутствие. Четвёртая — игнорирование того, что часть уровней в некоторых странах просто не существует: там, где нет административной единицы среднего уровня, обязательное поле сломает форму.
Наконец, при генерации для многих стран легко потерять связь между страной и набором символов. Если для всех стран использовать один и тот же пул названий, вы получите правдоподобную структуру с неправильным содержанием. Полезно прогонять такие наборы через проверку и нормализацию, о которой рассказано в материале про проверку и нормализацию адресов, хотя бы для того, чтобы увидеть, какие сочетания она забракует.
Как выгружать наборы для проверок на данных
Когда записей нужно много, их выгружают в таблицу или текстовый файл и подают тесту как источник данных. У этого подхода есть несколько подводных камней, и первый из них — кодировка. Если выгрузка сохраняется не в UTF-8, диакритика и нелатинские символы превратятся в мусор ещё до того, как попадут в тест, и вы будете искать ошибку в форме вместо ошибки в файле.
Второй камень — ведущие нули. Индекс или номер дома, начинающийся с нуля, при открытии таблицы в программе, которая считает такие значения числами, теряет первый знак. Один и тот же файл ведёт себя по-разному в зависимости от того, чем его открыли, поэтому для полей с ведущими нулями нужен текстовый тип.
Третий камень — разделители внутри значений. В адресной строке встречаются запятые, а в некоторых странах и точки с запятой, и наивный разбор файла разорвёт запись на лишние колонки. Четвёртый — переносы строк внутри одного значения: если адрес сохранён в две строки, тест получит две записи вместо одной.
Отсюда практический вывод: фиксируйте порядок колонок, храните адрес как одну строку или как заранее определённые части, и проверяйте выгрузку тем же тестом, который её читает. Набор, который вы не можете прочитать обратно, бесполезен, каким бы разнообразным он ни был.
Где случайные адреса полезны в нагрузочных проверках?
В нагрузочных проверках важна не правдивость отдельной записи, а поведение системы на объёме. Здесь случайные адреса дают то, чего не даст фиксированный набор: тысячи различных значений, которые проверяют индексы базы, сортировку, поиск и уникальность. Если все записи одинаковы, вы не увидите, как система ведёт себя при разбросе длин и при необычных сочетаниях символов.
Второе применение — проверка ограничений. Уникальность почтового ящика или номера документа проверяется только тогда, когда значения действительно разные. Третье — фаззинг форм: набор из граничных значений, слишком длинных названий и записей с необычной пунктуацией находит дефекты разбора и отображения, которые обычные данные не задевают.
При этом полностью отказываться от эталонных записей нельзя. Нагрузочный набор должен включать несколько фиксированных адресов, чтобы результат прогона можно было сравнить с предыдущим и заметить регрессию не только по времени отклика, но и по содержимому. Разные страны удобно масштабировать отдельными наборами, и об этом есть отдельный материал про масштабирование тестовых данных по странам.
Как проверить качество случайного набора?
Первый признак хорошего набора — согласованность внутри каждой записи. Проверить её можно автоматически: сопоставить город со справочником страны, почтовый индекс с городом, телефонный код с населённым пунктом. Если хотя бы одна связка нарушается, значит генератор собирает поля независимо друг от друга, и это нужно исправить до того, как набор попадёт в тесты.
Второй признак — распределение значений. Если из тысячи записей девятьсот относятся к одному городу, набор формально разнообразен, но проверяет мало. Полезно построить простую сводку: сколько уникальных городов, сколько уникальных индексов, как распределены длины названий. Это несколько минут работы, которые окупаются сразу, потому что пустые и однообразные участки видны без всякой статистики.
Третий признак — отсутствие повторов по тем полям, где уникальность требуется. Проверка уникальности почтового ящика или номера документа ломается на дублирующихся значениях, и виноват в этом будет набор, а не код приложения.
Четвёртый признак — читаемость на глаз. Возьмите случайные десять записей и прочитайте их. Если среди них попадаются строки, которые вы не хотели бы видеть в отчёте о дефекте, значит генератор смешивает языки, регистры или форматы. Автоматическая проверка такого не покажет, ей не с чем сравнивать.
Пятый признак — поведение на границах. Полезно проверить, что происходит при очень большой выборке, при повторной генерации с тем же ключом и при запросе страны, для которой данных мало. Устойчивый генератор в этих случаях либо честно сообщает об ограничении, либо отдаёт меньше записей, но не выдаёт бессмысленные сочетания полей.
Полезно также сохранить один такой набор как эталонный и сравнивать с ним новые. Расхождение в распределении сразу бросается в глаза, тогда как при взгляде на отдельную запись ничего подозрительного не видно. Эталон не должен быть большим: нескольких десятков записей достаточно, чтобы заметить изменение характера генерации после правки кода.
Границы синтетических адресов
Записи, которые выдаёт генератор адресов, синтетические. Они построены по правилам формата и согласованы между собой, но за ними не стоит ни одно реальное здание и ни один реальный человек. Такую запись нельзя использовать для отправки корреспонденции, нельзя предъявлять как подтверждение места жительства и нельзя использовать, чтобы выдать себя за другого.
Назначение этих образцов — проверка ваших собственных форм, справочников, правил нормализации и тестовых окружений. Всё, что выходит за эти рамки, лежит вне задачи, и об этом стоит написать прямо в документации проекта.
Что делать дальше
Начните с одного сценария: возьмите форму, которую сейчас заполняют вручную, и замените ручные данные набором из генератора. Зафиксируйте ключ для эталонных случаев, добавьте отдельный набор для исследовательских прогонов и проверьте, что выгрузка читается обратно без потери знаков. Такой порядок снимает сразу две проблемы: тесты перестают падать из-за случайности, а набор остаётся достаточно разнообразным, чтобы находить настоящие дефекты.