ios - 在 iOS 测试中以编程方式模拟 GPS 位置

标签 ios swift gps automated-tests xctest

我想用 Swift 编写 UI 测试,在我们的应用程序中截取 map 各个位置的屏幕截图。为此,我需要在测试期间模拟虚假的 GPS 数据。

有一些解决方案(https://blackpixel.com/writing/2016/05/simulating-locations-with-xcode-revisited.html)使用 GPX 文件并在 Xcode 中使用 Debug > Simulate Location 模拟位置,但我需要它完全自动化。理想情况下类似于 Android 中的 LocationManager

最佳答案

我在编写 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()

关于ios - 在 iOS 测试中以编程方式模拟 GPS 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45876613/

相关文章:

ios - 快速条码扫描

security - 如何确保发送到服务器的GPS位置准确?

ios - 在 Swift 3 中使用 LibXML2 下载时从服务器解析大型 XML

swift - 无法向 UIAlertController (Swift) 添加警报操作

android - 如何确定我当前的位置(经度、纬度和高度)?

android - Android应用程序开发如何自动获取用户位置坐标?

ios - OpenGL ES 1.1 iPhone5+ IOS 8 黑屏

objective-c - 我可以通过无线方式将 localizable.strings 文件加载到 iOS 应用程序中吗

ios - 如何使用 RestKit 映射 JSON 数组

ios - 在 Swift 中用自定义对象填充数组