我在编写 UI 测试时也遇到过类似的问题,因为模拟器/系留设备无法完成您可能想要的一切。我所做的是编写模拟所需行为(我通常无法控制的行为)的模拟。
将自定义位置管理器替换为 CLLocationManager 将允许您完全控制位置更新,因为您可以通过 CLLocationManagerDelegate 方法以编程方式发送位置更新:locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])。
创建一个类MyLocationManager,使其成为CLLocationManager 的子类,并让它覆盖您调用的所有方法。不要在被覆盖的方法中调用 super,因为 CLLocationManager 永远不会真正接收到方法调用。
class MyLocationManager: CLLocationManager {
override func requestWhenInUseAuthorization() {
// Do nothing.
}
override func startUpdatingLocation() {
// Begin location updates. You can use a timer to regularly send the didUpdateLocations method to the delegate, cycling through an array of type CLLocation.
}
// Override all other methods used.
}
delegate 属性不需要被覆盖(也不能被覆盖),但您可以作为 CLLocationManager 的子类访问它。
要使用MyLocationManager,您应该传入启动参数,告诉您的应用程序是否是 UITest。在您的测试用例的setUp 方法中插入这行代码:
app.launchArguments.append("is_ui_testing")
在测试时将 CLLocationManager 存储为 MyLocationManager 属性。不测试时 CLLocationManager 将照常使用。
static var locationManger: CLLocationManager = ProcessInfo.processInfo.arguments.contains("is_ui_testing") ? MyLocationManager() : CLLocationManager()