pointfreeco / swift-snapshot-testing

📸 Delightful Swift snapshot testing.
https://www.pointfree.co/episodes/ep41-a-tour-of-snapshot-testing
MIT License
3.74k stars 570 forks source link

Image fetched asynchronously sometimes won't show in snapshots #881

Closed spelaez closed 1 month ago

spelaez commented 1 month ago

Describe the bug Using an image that is fetched asynchronously might won't show sometimes on the light mode snapshot variant

To Reproduce This should repro mostly on a first run of the tests There's an ImageProvider dependency that fetches an image in an async fashion The test is provided with a version of this that returns an image immediately and the snapshots are captured with a wait of 0.1 SnapshotsBug.zip

Expected behavior Image should show always in the snapshots

Screenshots testImage compact_Dark testImage compact

Environment

mbrandonw commented 1 month ago

Hi @spelaez, your code is producing purple runtime warnings letting you know that something isn't quite right:

Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.

You can fix this by making the model @MainActor, or at least the task method.

Overall I am seeing pretty deterministic test passes, but I understand it may be different for you. This may just be the reality of snapshot testing, which is not an exact science. We do have plans in the future to make assertSnapshot an async function, which could help with situations like this, but it would be a big overhaul to the library and a 2.0 breaking change.

You could emulate the async style of snapshot testing doing something like this:

let view = ContentView(model: viewModel)
let controller = UIHostingController(rootView: view)
_ = controller.view
try await Task.sleep(for: .seconds(0.03))
assertSnapshot(
  of: controller,
  named: "\(density)"
)

Since I don't feel this is directly an issue with the library I am going to convert it to a discussion. Please feel free to continue the conversation over there, or maybe others have tips they can share to help you out.