Reliably testing code that adopts Swift Concurrency?

The point of my post is to show that the mere introduction of async-await to otherwise simple, easy-to-test code turns it into something that seems to be impossible to test. I could also rewrite the equivalent code in Combine using NotificationCenter's publisher API and everything becomes easy to test.

I would love to use async-await code and have a path forward to test it. Rewriting all async-await code when you want to test it doesn't seem like a practical way forward for users of the language, especially when Swift Concurrency has been promoted so much.

This provides a workaround for the second Task.yield() but not the first. There's no material condition that changes between calling await vm.task() and the view model's for await _ in, but the latter loop must start before notificationCenter.post is called in the test.

This example is purposefully simple to demonstrate the root problem, which only gets worse for complex, async logic that is more valuable to test.

3 Likes