Перед выпуском приложения QR-код входного билета уже сохранён в PNG, а предварительный просмотр выглядит нормально. Но при сканировании могут возникнуть проблемы: масштабирование с интерполяцией, обрезанные края или слишком слабый контраст между кодом и фоном. Вместо проверки одного лишь факта существования файла лучше извлечь с облачного Mac изображение, которое приложение экспортировало в итоге, повторно прочитать его с помощью Vision и сверить содержимое. Такая проверка на уровне файла хорошо подходит для регрессионных тестов iOS.
Сначала определим критерии приёмки
Здесь проверяется PNG, фактически записанный приложением, а не QR-код, созданный самим тестовым скриптом. Фиксированные тестовые данные — case-123; тестовая точка входа приложения должна записать соответствующее изображение в Documents/qr-sample.png внутри своей песочницы. Если продукт только рисует QR-код на экране, сначала получите файл через существующую функцию экспорта. Не создавайте отдельный тестовый генератор, выдавая его результат за рабочий вывод приложения.
Критериев три: файл удаётся извлечь из контейнера приложения; Vision обнаруживает ровно один QR-код; декодированная строка в точности совпадает с ожидаемой. Хеш файла не подходит в качестве основной проверки: изменение параметров кодирования или метаданных PNG может изменить байты, не затронув содержимое QR-кода.
«Считываемость» здесь относится только к экспортированному цифровому изображению. Фокусировка камеры, яркость экрана и размер печати добавляют другие переменные, поэтому проверка файла не заменяет реальное сканирование.
Извлечём итоговый файл из симулятора
Сначала запустите тестовую точку входа в уже работающем симуляторе iOS и убедитесь, что приложение записало файл по согласованному пути. Для команд ниже переменная окружения BUNDLE_ID должна содержать настоящий bundle identifier тестируемого приложения; get_app_container вернёт путь к его контейнеру данных.
test -n "$BUNDLE_ID" || exit 2
APP_DATA=$(xcrun simctl get_app_container booted "$BUNDLE_ID" data) || exit 1
mkdir -p artifacts
cp "$APP_DATA/Documents/qr-sample.png" artifacts/qr-sample.png
file artifacts/qr-sample.png
Если cp завершается с ошибкой, сначала проверьте, запущено ли приложение в текущем работающем симуляторе и действительно ли экспорт записывает файл в Documents. Не подставляйте вместо него одноимённую картинку с машины разработчика: тогда регрессионный тест обойдёт приложение. Если приложение каждый раз создаёт несколько файлов, тестовая точка входа должна использовать стабильное имя файла и удалять старые файлы перед каждым запуском, чтобы не принять результат предыдущего запуска за новый.
Декодируем код через Vision и сверим данные
Сохраните приведённый ниже код в рабочем каталоге как qr-check.swift. Скрипт принимает путь к PNG и ожидаемый текст. При ошибке чтения файла, распознавания или сравнения он завершается с ненулевым кодом, который может напрямую обработать конвейер.
import Foundation
import Vision
guard CommandLine.arguments.count == 3 else {
fputs("usage: swift qr-check.swift IMAGE EXPECTED\n", stderr)
exit(2)
}
let url = URL(fileURLWithPath: CommandLine.arguments[1])
let expected = CommandLine.arguments[2]
let request = VNDetectBarcodesRequest()
request.symbologies = [.qr]
do {
try VNImageRequestHandler(url: url, options: [:]).perform([request])
let codes = (request.results ?? []).filter { $0.symbology == .qr }
guard codes.count == 1,
codes[0].payloadStringValue == expected else {
fputs("QR count or payload mismatch\n", stderr)
exit(1)
}
print("QR payload verified")
} catch {
fputs("QR image could not be analyzed\n", stderr)
exit(1)
}
Выполните swift qr-check.swift artifacts/qr-sample.png case-123. Одной проверки количества распознанных кодов недостаточно: успешно считанный код всё ещё может содержать старый номер заказа, неверный префикс или обрезанный текст. Не используйте и настоящие учётные данные в тестовых данных. Если рабочая нагрузка содержит чувствительные поля, для проверки формата и логики разбора достаточно специальных недействительных тестовых значений.
Локализуем сбои по этапам
Сначала изучите экспортированный файл, затем результат распознавания и лишь после этого возвращайтесь к коду генерации QR-кода. Так проще отделить ситуацию «файл не экспортирован» от ситуации «файл есть, но код не читается».
| Симптом | Что проверить в первую очередь |
|---|---|
| PNG не найден | Выбор симулятора, bundle identifier, путь в песочнице и удаление старых файлов |
| Vision не находит код | Не обрезано ли изображение, не уменьшено ли до миниатюры и не применялась ли обработка с потерями |
| Распознано несколько кодов | Не попали ли в экспортированное изображение другие QR-коды |
| Данные не совпадают | Текст перед кодированием, кодировку символов, кеш и момент экспорта |
Если приложение генерирует QR-код через Core Image, сначала сохраните полные границы изображения из outputImage генератора, затем увеличьте его в целое число раз и только после этого запишите PNG. Проверьте, не уменьшает ли путь через функцию отправки или снимок экрана изображение ещё раз с интерполяцией: гладкий на вид предпросмотр не означает, что границы квадратов остались чёткими. Для тёмной темы также проверьте цвета конечного файла. Фон интерфейса и фон экспортированного изображения могут различаться, а прозрачные области на другом фоне — терять контраст.
Не допускайте ложных результатов
Зафиксируйте одно тестовое изображение, одни конкретные данные и один путь вывода, но каждый раз берите файл, созданный приложением в текущем запуске. Если нужно проверить данные другой длины, символы вне ASCII или строки с разделителями, создайте отдельные тестовые случаи и сравнивайте результат каждого с его ожидаемым значением. Не объединяйте несколько ожидаемых строк условием «совпала хотя бы одна». Успешное декодирование QR-кода также не означает, что бизнес-ссылка работает. Если нужно проверить переход, тестируйте разбор и маршрутизацию на другом уровне.
Добавим проверку в регрессионный процесс
После существующих тестов в симуляторе выполните команды извлечения файла и Swift-скрипт. Ненулевой код завершения любого шага должен останавливать текущий прогон. При сбое сохраните PNG этого запуска и вывод ошибок скрипта: они помогут понять, изменился ли путь экспорта или обработка изображения ухудшила его качество. После успешной проверки достаточно записать её статус; долго хранить изображения с бизнес-данными не нужно.
В итоге проверьте четыре вещи: изображение получено из конечного вывода приложения; остаточный файл прошлого запуска не использован; Vision считал ровно один код; данные полностью совпадают с фиксированным тестовым значением. Так у файловой регрессионной проверки QR-кода появятся чёткие, воспроизводимые границы. Если код предназначен для показа на экране или печати, дополните её проверкой сканирования на реальном устройстве.
Часто задаваемые вопросы
Заменяет ли Vision сканирование камерой настоящего устройства?
Нет. Vision проверяет читаемость файла и его содержимое; яркость экрана, фокус камеры и размер отпечатка нужно испытывать отдельно.
Почему нельзя генерировать QR-код внутри самого проверочного скрипта?
Так проверяется только скрипт. Конечный PNG приложения позволяет обнаружить ошибки масштабирования, цветов, обрезки и сохранения в самом приложении.
Проверьте следующий шаг на выделенном физическом Mac mini
VMCommit предлагает выделенные физические Mac mini с чипом M4 в аренду на день, неделю, месяц или квартал. Выберите модель и локацию, а затем проверьте доступность в реальном времени в панели управления.