final class LocationManager: CLLocationManager {
…
// Allow location to be set for testing. If it is set, the set value will be returned, else the current location.
private var _location: CLLocation?
@objc dynamic override var location: CLLocation? {
get {
let usedLocation = _location ?? super.location
return usedLocation
}
set {
self._location = newValue
}
}
…
} // class LocationManager
private func setFakeLocation(name: String) -> Bool {
helperApp.activate() // Activate helper app
let cell = helperApp.tables.cells.staticTexts[name]
let cellExists = cell.waitForExistence(timeout: 10.0)
if cellExists {
cell.tap() // Tap the tableViewCell that displays the selected item
}
appUnderTest.activate() // Activate the app under test again
return cellExists
}
最后,调用这个函数:
func test_setFakeLocation() {
// Test that the helper app can send a fake location, and this location is handled correctly.
// when
let fakeLocationWasTappedInHelperApp = setFakeLocation(name: "Location 1")
// then
XCTAssert(fakeLocationWasTappedInHelperApp)
…
}
4条答案
按热度按时间bvk5enib1#
选择测试中的一个,它应该是您选择位置时选择的测试目标。在此之前,你应该有gpx文件的任何位置,你想要的。有网站可在线生成一个为您的位置.
sr4lhrrt2#
您可以使用自定义GPX file模拟位置的变化。使用您所需的路径或路线创建一个,然后从产品->方案->编辑方案中选择它...
h22fl7wq3#
我知道这应该容易得多,但我找不到一个不那么复杂的解决方案。但它是灵活的和工作。
其基本思想是使用一个helper应用程序,该应用程序将测试位置发送到被测应用程序。
以下是所需的步骤:
1)设置助手应用:
这是一个在tableView中显示测试位置的单视图应用程序:
如果点击tableView中的一行,助手应用程序将尝试打开一个包含相应测试位置坐标的自定义URL。
2)准备待测应用处理此自定义URL:
在info.plist中插入以下行:
这将注册自定义URL“
setFakeLocation://
”。为了让被测应用能够处理此URL,AppDelegate
中的以下两个函数必须返回true
:此外,还必须实现实际打开URL的函数:
本质上,它从URL中提取坐标,并在位置管理器的委托中调用函数
didUpdateLocations
,就像真实的的位置管理器已经更新了位置一样。3)设置CLLocationManager的子类:
但是,测试中的应用程序很可能会访问位置管理器的
location
属性,该属性也必须设置。在CLLocationManager
中,此属性是只读的,无法设置。因此,必须使用CLLocationManager
的自定义子类,并覆盖此属性:在正常操作中,不设置子类的属性
location
,即nil
。所以当它被读取时,它的超类的属性location
,真实的的CLLocationManager
被读取。但是,如果在测试期间将此属性设置为测试位置,则将返回此测试位置。4)在被测应用UI测试中选择测试位置:
这可以通过多应用UI测试来实现。它需要访问助手应用程序:
在
class ShopEasyUITests: XCTestCase
的UITests中,定义一个属性并向其分配通过其bundleIdentifier定义的应用
此外,定义一个函数,通过激活helper应用程序并点击tableView中请求的行来设置所需的测试位置,然后切换回测试中的应用程序:
最后,调用这个函数:
5)进一步说明:
当然,测试中的应用程序和助手应用程序必须安装在同一模拟器上。否则,两个应用程序无法通信。
可能相同的方法可以用于UI测试推送通知。不需要在
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
中调用locationManagerDelegate?.locationManager(locationManager, didUpdateLocations: [location])
,可以在那里调用lc8prwob4#
从iOS 16.4、macOS 13.3和Xcode 14.3开始,提供了一个新的XCTest API,让您可以非常轻松地完成此操作。
https://developer.apple.com/documentation/xctest/xcuidevice/4111083-location
您可以通过在
XCUIDevice
上设置location
属性来模拟设备的位置。