Разработка приложений с дополненной реальностью (AR) для iOS с помощью ARKit сопряжена с уникальными проблемами тестирования. Традиционные методы ручной проверки на устройстве не масштабируются и подвержены ошибкам, особенно при частых обновлениях. Интеграция отладки и тестирования ARKit в конвейер непрерывной интеграции и доставки (CI/CD) — ключ к обеспечению стабильности и качества. Эта статья проведет вас через стратегии автоматизации тестирования ARKit, от симуляции данных датчиков до скриншот-тестов и unit-тестирования бизнес-логики.
Основная сложность тестирования ARKit заключается в его зависимости от физического мира: камера, освещение, поверхности, движение. В среде CI/CD, которая обычно работает на серверах без камер, это кажется непреодолимым препятствием. Однако Apple предоставляет мощные инструменты для симуляции и записи данных AR-сессий. Ключевым компонентом является класс `ARWorldMap` и возможность записи и воспроизведения сессий через `ARReplayKit` (для ручного захвата) и, что более важно для автоматизации, использование файлов `.arobject` или симуляция через `ARCamera` и `ARFrame`.
Первый подход — это создание детерминированных тестовых сцен с помощью сохраненных `ARWorldMap`. Вы можете записать карту окружения с реального устройства один раз (например, офисный стол с хорошим освещением) и сохранить ее как файл. Этот файл затем можно загружать в тестовой среде для обеспечения стабильного контекста.
Пример кода для сохранения и загрузки `ARWorldMap` в тестовом target вашего приложения (используя `XCTest`):
```
import ARKit
import XCTest
@testable import YourARApp
class ARKitSnapshotTests: XCTestCase {
var arSession: ARSession!
var worldMapURL: URL!
override func setUp() {
super.setUp()
arSession = ARSession()
worldMapURL = Bundle(for: type(of: self)).url(forResource: "test_office_map", withExtension: "arworldmap")
}
func testWorldMapLoading() {
// Загружаем сохраненную карту мира
let data = try! Data(contentsOf: worldMapURL)
let worldMap = try! NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: data)
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = worldMap
let expectation = self.expectation(description: "Session runs with world map")
arSession.delegate = self
arSession.run(configuration)
// Ждем, пока сессия обновит свое состояние
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
expectation.fulfill()
}
waitForExpectations(timeout: 5.0)
// Проверяем, что сессия имеет отслеживаемые якоря
XCTAssertFalse(arSession.currentFrame?.anchors.isEmpty ?? true)
}
}
```
Второй, более продвинутый метод — это симуляция AR-сессии «с нуля» без реальной камеры. Это можно сделать, создавая мок-объекты для `ARSession` и `ARFrame`, подставляя заранее подготовленные данные. Это идеально для unit-тестирования бизнес-логики вашего приложения, которая реагирует на AR-события (например, размещение виртуального объекта при обнаружении плоскости).
Пример мок-объекта `ARFrame` и теста логики размещения:
```
// Вспомогательный класс для создания мок-ARFrame
class MockARFrame: ARFrame {
let _anchors: [ARAnchor]
init(anchors: [ARAnchor]) {
_anchors = anchors
super.init()
}
override var anchors: [ARAnchor] { return _anchors }
}
// Тест для вашего ViewController или Manager
func testVirtualObjectPlacementOnPlaneAnchor() {
// 1. Создаем мок-плоскость (ARPlaneAnchor)
let planeAnchor = ARPlaneAnchor(transform: simd_float4x4(diagonal: [1,1,1,1]), center: [0,0,0], extent: [0.5, 0.5])
// 2. Создаем мок-ARFrame с этой плоскостью
let mockFrame = MockARFrame(anchors: [planeAnchor])
// 3. Инициируем ваш менеджер или контроллер
let objectManager = VirtualObjectManager()
objectManager.session(ARSession(), didUpdate: [mockFrame])
// 4. Проверяем, что логика корректно отреагировала на появление плоскости
XCTAssertTrue(objectManager.canPlaceObject)
XCTAssertEqual(objectManager.detectedPlanes.count, 1)
}
```
Третий критически важный аспект — это визуальное регрессионное тестирование. Поскольку AR — это визуальный опыт, необходимо убедиться, что рендеринг 3D-моделей, шейдеры и взаимодействия не ломаются после изменений кода. Здесь на помощь приходят скриншот-тесты (snapshot tests). Библиотека `iOSSnapshotTestCase` (ранее FBSnapshotTestCase) или более современный `XCTest` с функцией `XCTAttachment` могут использоваться для захвата изображения `ARSCNView` или `ARSKView` в контролируемых условиях.
Пример интеграции snapshot-теста:
```
func testARRenderingSnapshot() {
let arViewController = ARViewController()
arViewController.loadViewIfNeeded()
// Загружаем тестовую world map и запускаем сессию (как в первом примере)
// ... код настройки ARSession ...
// Даем сцене время на рендеринг
let expectation = self.expectation(description: "Scene rendered")
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
expectation.fulfill()
}
waitForExpectations(timeout: 5.0)
// Делаем скриншот ARSCNView
let snapshot = arViewController.sceneView.snapshot()
// Сравниваем с эталонным изображением (эталон должен быть заранее сохранен)
let referenceImage = UIImage(named: "test_scene_reference", in: Bundle(for: type(of: self)), compatibleWith: nil)!
XCTAssertEqual(snapshot.pngData(), referenceImage.pngData(), tolerance: 0.001) // Допуск для незначительных различий
}
```
Для интеграции в CI/CD (например, с использованием GitHub Actions, GitLab CI или Bitrise) вам потребуется настроить симулятор iOS с поддержкой AR. Хотя симулятор iOS не имеет реальной камеры, он может запускать ARKit-сессии в симулированном окружении. В конфигурационном файле CI необходимо указать симулятор с поддержкой AR (`iPhone 15 Pro` или новее в списке симуляторов). Тесты, основанные на моках и сохраненных данных, будут выполняться стабильно.
Заключительный совет: структурируйте код вашего AR-приложения, максимально отделяя логику обработки ARKit (работа с сессией, якорями) от логики рендеринга и бизнес-логики. Это позволит покрыть unit-тестами большую часть кода, оставив для интеграционных и snapshot-тестов только тонкий слой взаимодействия с ARKit. Автоматизация тестирования ARKit требует первоначальных инвестиций, но окупается сторицей в виде стабильных релизов и уверенности в качестве вашего AR-опыта.
Надежная AR-разработка: Интеграция отладки ARKit в конвейер CI/CD
Практическое руководство по автоматизации тестирования и отладки ARKit в CI/CD. Рассматриваются методы: использование сохраненных ARWorldMap, создание мок-объектов для unit-тестов, snapshot-тестирование визуала и настройка симуляторов в среде непрерывной интеграции. Приводятся примеры кода на Swift.
400
1
Комментарии (7)