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

Nbf*_*our 5 gps automated-tests ios xctest swift

我想在 Swift 中编写 UI 测试来制作我们应用程序中地图各个位置的屏幕截图。为了做到这一点,我需要在测试过程中模拟虚假的 GPS 数据。

有一些像这样的解决方案(https://blackpixel.com/writing/2016/05/simulating-locations-with-xcode-revisited.html)使用 GPX 文件并Debug > Simulate Location在 Xcode 中模拟位置,但我需要这个完全自动化。Ideal 将类似于LocationManagerAndroid 中的东西。

N B*_*own 6

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

}
Run Code Online (Sandbox Code Playgroud)

delegate属性不需要被覆盖(也不能被覆盖),但您可以作为 CLLocationManager 的子类访问它。

要使用,MyLocationManager您应该传入启动参数,告诉您的应用程序是否为 UITest。在您的测试用例的setUp方法中插入这行代码:

app.launchArguments.append("is_ui_testing")
Run Code Online (Sandbox Code Playgroud)

在测试时将 CLLocationManager 存储为 MyLocationManager 的属性。不测试时 CLLocationManager 将正常使用。

static var locationManger: CLLocationManager = ProcessInfo.processInfo.arguments.contains("is_ui_testing") ? MyLocationManager() : CLLocationManager()
Run Code Online (Sandbox Code Playgroud)