我已經找到了一些可以可靠工作的方法,但是我看不出我對解決方案100%滿意。
首先,我在didFinishLaunchingWithOptions避免應用程序的主界面做到這一點得到加載,由此引起的一切排序混亂的時候也嘗試寫應用程序的主屏幕測試:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
BuddyBuildSDK.setup()
//Apply Itison UI Styles
ItIsOnUIAppearance.apply()
#if DEBUG
if let _ = NSClassFromString("XCTest") {
// If we're running tests, don't launch the main storyboard as
// it's confusing if that is running fetching content whilst the
// tests are also doing so.
let viewController = UIViewController()
let label = UILabel()
label.text = "Running tests..."
label.frame = viewController.view.frame
label.textAlignment = .center
label.textColor = .white
viewController.view.addSubview(label)
self.window!.rootViewController = viewController
return true
}
#endif
然後在測試中,一旦我已經完全建立在的UIViewController我需要做這樣的事情:
func wait(for duration: TimeInterval) {
let waitExpectation = expectation(description: "Waiting")
let when = DispatchTime.now() + duration
DispatchQueue.main.asyncAfter(deadline: when) {
waitExpectation.fulfill()
}
waitForExpectations(timeout: duration+1)
}
_ = viewController.view // force view to load
viewController.viewWillAppear(true)
viewController.view.layoutIfNeeded() // forces view to layout; necessary to get kingfisher to fetch images
// This is necessary as otherwise the blocks that Kingfisher
// dispatches onto the main thread don't run
RunLoop.main.run(until: Date(timeIntervalSinceNow:0.1));
viewController.view.layoutIfNeeded() // forces view to layout; necessary to get kingfisher to fetch images
wait(for: 0.1)
FBSnapshotVerifyView(viewController.view)
,如果我不這樣做的基本問題是,翠鳥只有啓動時FBSnapshotVerifyView迫使視圖加載圖像被解僱(和Ki一樣ngFisher通過將塊分派給後臺線程來加載映像,後臺線程然後將塊分派回主線程),這太遲了 - 發送到主線程的塊無法運行,因爲主線程在FBSnapshotVerifyView()中被阻塞。沒有對'layoutIfNeeded()'和RunLoop.main.run()的調用,KingFisher dispatch_async GCD到主隊列不會運行,直到/ next/test讓runloop運行,這太遲了。我不太滿意我的解決方案(例如,爲什麼我需要layoutIfNeeded()兩次並運行runloop兩次),所以我會非常欣賞其他想法,但我希望這至少可以幫助其他人這種情況發生在同樣的情況下,因爲它需要一點頭腦才能弄清楚發生了什麼。