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

问题描述:

我想在Swift中编写UI测试,在我们的应用中制作地图各个地方的截图。为了做到这一点,我需要在测试过程中模拟伪造的GPS数据。以编程方式模拟iOS测试中的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() 

你不能。 CLLocationManager在委托人的帮助下给你你的位置,你有任何设置这个位置的方法。

您可以创建一个CLLocationManager模拟器类,它可以提供一些位置的时间。 或者您可以将您的测试与时间戳GPX同步。

+0

这是严重不可能的吗? 所以我最好的选择是使用时间戳GPX文件并在每次位置更改时都截图。 – Nbfour