根據是否運行Xcode UI測試,我如何定義全局變量?我試圖做到這一點:根據是否運行Xcode UI測試來定義全局變量
#if UITESTS
let api = StubbedAPI()
#else
let api = RealAPI()
#endif
這些都是全局變量,所以我不能在文件範圍內來電或NSProcessInfo.processInfo().environment
NSProcessInfo.processInfo().arguments
。
根據是否運行Xcode UI測試,我如何定義全局變量?我試圖做到這一點:根據是否運行Xcode UI測試來定義全局變量
#if UITESTS
let api = StubbedAPI()
#else
let api = RealAPI()
#endif
這些都是全局變量,所以我不能在文件範圍內來電或NSProcessInfo.processInfo().environment
NSProcessInfo.processInfo().arguments
。
UI測試目標作爲與您的應用程序分開的過程運行。這意味着您不能在測試目標中設置預處理器宏,並期望應用程序知道它們。測試可以與應用程序通信的唯一方法是通過您提到的兩個processInfo
設置。
使用這些是動態的,而您提出的解決方案是靜態的。但是,仍然有可能通過蘋果給我們提供的工具來做你正在嘗試做的事情。
首先,創建StubbedAPI和RealAPI都符合的協議。
protocol API {
// ... //
}
class RealAPI: API {
// ... //
}
class StubbedAPI: API {
// ... //
}
接下來,創建一個配置類。這將用於告訴你的代碼在運行時使用哪個API。
struct Config {
var api: APIProtocol {
get {
return UITesting() ? RealAPI() : StubbedAPI()
}
}
}
private func UITesting() -> Bool {
return NSProcessInfo.processInfo().arguments.contains("UI-TESTING")
}
然後,通過配置檢索對API實現的引用。
class FooService {
private let api = Config().api;
}
最後,在UI Testing下啓動應用程序之前設置processInfo參數。
class UITests: TestCase {
let app = XCUIApplication()
override func setUp() {
super.setUp()
app.launchArguments = ["UI-TESTING"]
app.launch()
}
}
的api
屬性將生產運行的代碼和存根之一的,UI測試時設置爲真正的API。
這種方法有一些缺點。首先,您要向生產代碼引入實際的「殘留」API。這有一個實際在生產中使用它的開發者的潛在缺點。其次,你需要創建API
協議,只有一個「真實」的對象實現它。不幸的是,鑑於UI測試和Swift的當前狀態,這是我提出的最佳解決方案。