gpt4 book ai didi

ios - KingFisher + UICollectionView + XCTest 与 NSURLSession 模拟不加载图像

转载 作者:行者123 更新时间:2023-11-29 00:12:48 25 4
gpt4 key购买 nike

我正在为我的应用程序中的某些 View / View Controller 编写单元测试。

我的应用程序使用 UICollectionView,包含使用 kingfisher 加载的图像的单元格.我正在使用 FBSnapshotTestCase记录 View 的图像并将它们与已知的良好图像进行比较(顺便说一句,当我们的开发人员拥有拉取请求时,使用 buddybuild's CI 自动运行测试,这真的很酷)。

我正在使用 NSURLSession-Mock将预制数据(JSON 和图像)插入到测试中。

我的问题是,似乎很难编写获得用户看到的最终相同最终结果的测试;我经常发现(除非图像已经缓存 - 它们不是因为我清除了测试设置中的缓存以确保测试从干净状态运行!)我拍摄的所有屏幕截图都缺少图像, 仅显示占位符。

最佳答案

我已经找到了让它明显可靠地工作的方法,但我看不到我对我的解决方案 100% 满意。

首先,我在 didFinishLaunchingWithOptions 中执行此操作以避免加载应用程序的主 UI,这在尝试为应用程序的主屏幕编写测试时会造成各种困惑:

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)

如果我不这样做,基本问题是 KingFisher 仅在 FBSnapshotVerifyView 强制布局 View 时才开始加载图像,并且(因为 KingFisher 通过向后台线程分派(dispatch) block 来加载图像,然后分派(dispatch) block 回到主线程)这为时已晚 - 发送到主线程的 block 无法运行,因为主线程在 FBSnapshotVerifyView() 中被阻塞。如果没有调用 'layoutIfNeeded()' 和 RunLoop.main.run(),KingFisher dispatch_async GCD 到主队列不会运行,直到/next/测试让 runloop 运行,这已经太晚了。

我对我的解决方案不太满意(例如,我还不清楚为什么我需要两次 layoutIfNeeded() 并运行两次 runloop)所以非常感谢其他想法,但我希望这至少能帮助其他人遇到同样的情况,需要稍微挠头才能弄清楚发生了什么。

关于ios - KingFisher + UICollectionView + XCTest 与 NSURLSession 模拟不加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45952889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com