Open Filipsky5 opened 1 year ago
Hi @Filipsky5, I had the same problem. I solved it by overwriting AsyncImage: AsyncImage.swift
Now you can overwrite the image for the given url like this:
struct AsyncImagePreview: PreviewProvider {
static var previews: some View {
AsyncImage(url: URL(string: "http://example.com/image.png"))
.environment(\.imageProvider) { url in
guard url.absoluteString == "http://example.com/image.png"
else { return nil }
return UIImage(named: "mock")
}
}
}
I think I wrote a simple reproducer that highlights this problem after encountering it myself. I'm having the same issue testing views that have a task modifier.
It seems that wait(for:on:)
isn't actually waiting as I'd expect and instead the SwiftUI view is being snapshotted as it appeared in its initial state.
import SnapshotTesting
import SwiftUI
import XCTest
struct TaskView: View {
@State private var taskStarted = false
@State private var taskFinished = false
var body: some View {
VStack {
Text("Task Started: \(taskStarted.description)")
Text("Task Finished: \(taskFinished.description)")
}
.task {
taskStarted = true
try? await Task.sleep(nanoseconds: 5_000_000_000)
taskFinished = true
}
}
}
final class SwiftUISnapshotTests: XCTestCase {
func testTaskView() throws {
let taskView = TaskView()
.fixedSize()
assertSnapshot(of: taskView, as: .wait(for: 6.0, on: .image))
}
}
Snapshot:
After the 6 second wait, the 5 second artificial task has had plenty of time to complete and so you'd expect both Task Started and Task Finished to say true yet they indicate the initial state of the view.
Update: After reading the documentation of wait(for:on:)
I believe this isn't a bug but rather a misunderstanding of the purpose of wait(for:on:)
paired with a current limitation of swift-snapshot-testing.
I've found a couple of other discussion that I think are all focused around this same limitation, namely #582 and #669.
Describe the bug I would like to write a snapshot test that will test my SwiftUI view containing AsyncImage. To not be dependent on external API which holds images I added png files to my codebase and created a URL to it with
Bundle(for: type(of: self)).url(forResource: "testImage", withExtension: "png")
. To problem is that even with.wait
strategy forassertSnapshots
I'm not able to record snapshots with images, I'm only getting a placeholder. To Repro TestingAsyncImage.zip duce// And/or enter code that reproduces the behavior here.
Expected behavior I would expect that adding
.wait
strategy for 2 seconds toassertSnapshots
is long enough for AsyncImage to load the image from the URL which leads to local memory.Screenshots
Environment